
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  topropper.r                                                                            #
  #           Last Updated Funclist  :  10 Feb 2015,  1:08 PM (Tuesday)                                                        #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :  NA                                                                                     #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   topropper_ignorePunc    ( x )                                                                                            #
  #   topropper               ( x )                                                                                            #
  #   topropper_preopositions ( x )                                                                                            #
  #   topropper_withPunc      ( ... )                                                                                          #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #


#--------------------------------------------#
    topropper_tbl <- function(tbl, period_to=" ") {
      topropper_keywords(tbl, period_to=period_to)
    }

    topropper_keywords <- function (x, period_to=" - ", zAdjust=TRUE) {
      if (is.factor(x)) {
        levels(x) <- topropper_keywords(levels(x))
        return(x)
      }

      x.bak <- copy(x)

      ## Anything starting zX, leave as stylezed
      zXs <- grepl("z[A-Z]", x)

      ## coerce to lower for quicker grepping
      x %<>% tolower

      x <- gsub("(accounting|activity)([a-z])", "\\1_\\2", x)

      ## make sure to separate _id
      wordsWithId <- c("artist", "catalog", "country", "genre", "imprint", "isrc", "label", "release", "store", "subaccount", "track", "transactiontype", "period", "usd", "eur")
      x <- wordsWithId %>% regOr %>% sprintf("%sid\\b", .) %>% gsub(repl="\\1_id", x)

      ## All country Codes should be capitalized
      country_codes <- c("Ww", "Us", "Gb", "Se", "Es", "No", "De", "Nl", "Mx", "Au", "Br", "Dk", "Fr", "It", "Fi", "Ch", "Ar")
      ## If the second letter is a number then topropper() will not capitalize the first letter. And since we call tolower() earlier in this function, the first letter will remain lowercase
      wordsToCap.withNumbs <- c("d3")
      ## Other words to manually capitalize
      wordsToCap <- c("Ioda", "Oa", "Dms", "Id", "Upc", "Isrc", "Isbn", "Asni", "Ansi", "Sd", "Hd", "Os", "Arpu", "Usd", "Eur", "Cd", "Gpu", "Ugc", "Mgmt", "Cpm", "Rpm", "Cm", "Li", "Uri", "Url", "Utc", "Uid", "Tid", "Etl")

      wordsToCap %<>% c(country_codes) %>% c(wordsToCap.withNumbs)
      pat <- wordsToCap %>% 
                paste0("\\b", ., "\\b", collapse = "|") %>% 
                paste0("(", ., ")")

      if (!is.null(period_to)) {
        ## Avoid splitting numbers like 2.5
        repl <- sprintf("\\1%s\\2", period_to)
        pat1 <- "([^[:digit:]])\\.([^[:digit:]])"
        pat2 <- "(.)\\.([^[:digit:]])"
        pat3 <- "([^[:digit:]])\\.(.)"
        x %<>% gsub(pat1, repl, .)
        x %<>% gsub(pat2, repl, .)
        x %<>% gsub(pat3, repl, .)
      }

      x %>% gsub("_", " ", .) %>% 
            topropper_preopositions %>% 
            gsub(pat, "\\U\\1", ., ignore.case=FALSE, perl=TRUE) %>%
            gsub("Applemusic", "AppleMusic", .)  %>%
            gsub("Itunes", "iTunes", .)  %>%
            gsub("Spotifypremium", "SpotifyPremium", .) %>%
            gsub("Youtube", "YouTube", .) %>%
            gsub("Zarchive", "zArchive", .) %>%
            gsub("Zetl", "zETL", .) %>%
            gsub("Appleid", "AppleID", .) %>%
            gsub("Is Red", "is RED", .) %>%
            gsub("\\bCcur\\b", "CCur", .) %>%
            {if (zAdjust) gsub("Z([b-df-hk-np-tv-y])", "z\\U\\1", ., perl=TRUE, ignore.case=FALSE)} %>%
            ifelse(zXs, x.bak, .)
    }

    topropper_ignorePunc <- function(x, underscore_to_space=FALSE) {
      if (is.factor(x)) {
        levels(x) <- topropper_ignorePunc(levels(x))
        return(x)
      }

      if (underscore_to_space)
        x <- underscoreToSpace(x)
      
      # Makes Proper Capitalization out of a string or collection of strings. 
      # does NOT consider punctuation as a word splitter
      sapply(x, function(strn)
       { s <- strsplit(strn, "\\s")[[1]]
           paste0(toupper(substring(s, 1,1)), 
                 tolower(substring(s, 2)),
                 collapse=" ")}, USE.NAMES=FALSE)
    }

    topropper <- function(x, underscore_to_space=FALSE) {
      if (is.data.table(x))
        return(setnames(copy(x), paste("|", topropper_keywords(names(x)))))

      if (is.factor(x)) {
        levels(x) <- topropper(levels(x))
        return(x)
      }

      if (underscore_to_space)
        x <- underscoreToSpace(x)
      
      gsub("\\b([a-zA-Z])([a-zA-Z]+)", "\\U\\1\\L\\2", x, perl=TRUE)
    }

    topropper_preopositions <- function(x) {
      # TEST <- "AND AND TEST BUT TO"
      # TEST <- "AND AND TEST BUT TO GO"

      if (is.factor(x)) {
        levels(x) <- topropper_preopositions(levels(x))
        return(x)
      }

      ## Preopositions that should be forced to lowercase
      preps <- c("and", "of", "but", "to", "in", "for", "a", "the", "or", "by", "from", "nor", "on", "at", "with")
      preps %<>% c("vs", "is", "are", "was")

      ## wrap in '\\b' to ensure whole-word.  
      pat <- paste0("\\b", preps, "\\b", collapse="|")

      ## wrap in parens for grouping. 
      ##  the '(?!^)' is a lookaround to ensure not beginning of line
      pat <- paste0("(?!^)(", pat, ")")

      ## replace with lowercase, also calling topropper(x)
      gsub(pat, "\\L\\1", topropper(x), ignore.case=TRUE, perl=TRUE)
    }


    # topropper_withPunc <- function(...) {
    #   warning("The function `topropper_withPunc` has been renamed to simply `topropper`.\nThe former `topropper` is now `topropper_ignorePunc`.\n\n")
    # }

    ## compare: 
    # topropper_ignorePunc("last-one") # [1] "Last-one"
    #            topropper("last-one") # [1] "Last-One"
    #
    # testCase <- c("last one", "LAST ONE", "LAST-ONE", "lAST-oNE", "lAST oNE")
    # topropper(testCase)

#--------------------------------------------#
