R/emate_utils.R

Defines functions read_file_path emate_edit_content emate_paste emate_start emate_merge emate_gather

Documented in emate_edit_content emate_gather emate_merge emate_paste emate_start read_file_path

#' Read from file path
#'
#' A convenience function for reading file contents from a file path
#'
#' @param ... arguments to \code{file.path}
#' @export

read_file_path <- function(...) readr::read_file(file.path(...))

#' Emate edit content
#'
#' A series of string replacements to ensure that content is parsed correctly in emails
#'
#' @param content_in content to replace
#' @importFrom magrittr %>%
#' @export

emate_edit_content <- function(content_in){
  content_in %>%
    # For hosting images on Dropbox
    stringi::stri_replace_all_fixed("www.dropbox.com", "dl.dropboxusercontent.com") %>%
    # Backslash-escape quotes in emails
    stringi::stri_replace_all_fixed("\"", "\\\"") %>%
    # Replace "$" with "\$" (uses regex negative lookbehind to avoid "\\$")
    # so that two "$" close to each other are formatted correctly
    stringr::str_replace_all("(?<!\\\\)\\$", "\\\\$")
}

#' Paste consistently
#'
#' Pastes a set of arguments together, ensuring that two line breaks are between each argument
#'
#' @param ... arguments to \code{paste}
#' @export

emate_paste <- function(...){
  paste(..., sep = "\n") %>%
    stringr::str_replace_all("\n+", "\n\n")
}

#' Start email for mail merging
#'
#' Starts an email with a specified title, the month and year, and the person's first name.
#'
#' @param title title of email, given a level one header in Markdown
#' @param fn first name, to address the recipient by
#' @export

emate_start <- function(title, fn){
  date_text <- format(lubridate::today(), "%B %Y")

  emate_paste(
    glue::glue("# {title}"),
    glue::glue("## {date_text}"),
    glue::glue("Dear {fn},")
  )
}

#' Emate mail merge
#'
#' Conduct a simple mail merge using emate, based on different content, subject and TO address
#'
#' @param data_in data to merge on
#' @param to_var naked variable name for TO field
#' @param subject_var naked variable name for SUBJECT field
#' @param content_var naked variable name for content field
#' @param ... additional arguments to \code{emate}
#' @importFrom rlang !!
#' @export

emate_merge <- function(data_in, to_var, subject_var, content_var, ...){

  data_loop <- data_in %>%
    dplyr::transmute(
      email   = !!rlang::enquo(to_var),
      subject = !!rlang::enquo(subject_var),
      content = emate_edit_content(!!rlang::enquo(content_var))
    )

  for (i in seq_len(nrow(data_loop))) {
    data_i <- data_loop %>%
      dplyr::slice(i) %>%
      tidyr::gather()

    emate(email_content = data_i$value[3],
          email_to = data_i$value[1],
          email_subject = data_i$value[2],
          ...)
  }
}

#' Gather email data
#'
#' Email data can often have husband and wife in the same row, but this is unsuitable for merging
#'
#' @param data_in contact data to gather
#' @importFrom rlang .data
#' @export

emate_gather <- function(data_in){
  # Create unique identifier for each row
  data_rn <- data_in %>%
    dplyr::mutate(rn = dplyr::row_number())

  # Gather a selection of columns of the data frame
  data_rn %>%
    dplyr::select(.data$rn, .data$fn1, .data$fn2, .data$email1, .data$email2) %>%
    tidyr::gather("key", "value", -.data$rn) %>%
    dplyr::mutate(key2 = stringr::str_sub(.data$key, 1, -2),
                  rn2 = stringr::str_sub(.data$key, -1, -1)) %>%
    dplyr::select(-.data$key) %>%
    tidyr::spread(.data$key2, .data$value) %>%
    dplyr::filter(!is.na(.data$email) | rn2 == 1) %>%
    dplyr::select(-.data$rn2) %>%
    dplyr::inner_join(data_rn, by = "rn")
}
andrewjpfeiffer/mailmatr documentation built on Nov. 2, 2019, 1:52 p.m.