echo <- function(
msg,
...,
indent = 0,
sleep = 0,
fn_name = NULL,
timestamp = FALSE,
error = FALSE,
abort = FALSE,
warn = FALSE,
fg = NULL,
bg = NULL,
style = NULL,
notify = FALSE,
notification = list(
title = '',
subtitle = NA,
app_icon = NA,
content_image = NA,
command = NA,
open_iterm = FALSE
)
) {
# Update console with custom message and optional indent, current datetime and text styles.
#
# Arguments:
# msg {char} -- message to print to console
#
# Keyword Arguments:
# ... {char} -- additional arguments passed into sprintf()
# indent {int} -- indentation level of message printed to console (default: 0)
# sleep {numeric} -- number of seconds to pause after printing message (default: 0)
# fn_name {char} -- name of function to print in 'ERROR|Warning in function {}'
# (default: NULL)
# timestamp {logical} -- if TRUE, print timestamp before message (default: FALSE)
# error {logical} -- if TRUE, print 'ERROR: ' before message (default: FALSE)
# abort {logical} -- if TRUE, print 'ERROR (fatal): ' before message and exit
# program (default: FALSE)
# warn {logical} -- if TRUE, print 'WARNING: ' before message (default: FALSE)
# fg {char} -- foreground color of text (one of: "black", "red", "green",
# "yellow", "blue", "magenta", "cyan", "white", "silver") (default: NULL)
# bg {char} -- background color of text (one of: "bgBlack", "bgRed", "bgGreen",
# "bgYellow", "bgBlue", "bgMagenta", "bgCyan", "bgWhite") (default: NULL)
# style {char} -- text style (one or multiple of of: "bold", "blurred", "italic",
# "underline", "inverse", "hidden", "strikethrough") (default: NULL)
# notify {logical} -- if TRUE, send notification to macOS using macos_notify()
# notification {list} -- list containing notification properties, elements:
# title {char} -- title of notification
# subtitle {char} -- subtitle of notification
# app_icon {char} -- path to icon image to display in notification
# content_image {char} -- path to content image to display in notification
# command {char} -- shell command to execute upon clicking on notification
# open_iterm {logical} -- if TRUE, open "iTerm.app" when notification is clicked
#
# Returns:
# nothing
# Save original message as normal character string
msg_raw = crayon::strip_style(sprintf(msg, ...))
# Check for 'crayon' package for colorized text output
if (!requireNamespace("crayon", quietly = TRUE)) {
stop("Package \"crayon\" needed for echo() to work. Please install it.",
call. = FALSE)
}
require(crayon, quietly = TRUE)
# Parse color input parameters
define_style <- function(fg=NULL, bg=NULL, text_style=NULL) {
# Define custom text style
style = list()
if (!is.null(fg) || !is.null(bg)) {
if (!is.null(fg)) { style$fg = make_style(fg) }
if (!is.null(bg)) { style$bg = make_style(bg) }
custom_style = do.call(combine_styles, style)
}
if (!is.null(text_style)) {
if("reset" %in% text_style) custom_style = custom_style$reset
if("bold" %in% text_style) custom_style = custom_style$bold
if("blurred" %in% text_style) custom_style = custom_style$blurred
if("italic" %in% text_style) custom_style = custom_style$italic
if("underline" %in% text_style) custom_style = custom_style$underline
if("inverse" %in% text_style) custom_style = custom_style$inverse
if("hidden" %in% text_style) custom_style = custom_style$hidden
if("strikethrough" %in% text_style) custom_style = custom_style$strikethrough
}
if (!is.null(fg) || !is.null(bg)) {
return(custom_style)
} else {
return(NULL)
}
}
style = define_style(fg, bg, text_style=style)
if (!is.null(style)) { msg = style(msg) }
# Add error colorized text to message
if (error || abort || warn) {
style_error = combine_styles(crayon::red, crayon::bold)
style_warn = combine_styles(crayon::yellow, crayon::bold)
msg = sprintf("%s%s%s %s",
ifelse(error || abort, style_error("ERROR"), style_warn("WARNING")),
ifelse(abort, style_error(" (fatal)"), ""),
ifelse(
is.character(fn_name),
ifelse(error || abort,
style_error(sprintf(" in function %s():", fn_name)),
style_warn(sprintf(" in function %s():", fn_name))),
ifelse(error || abort, style_error(":"), style_warn(":"))),
msg)
}
tab = ifelse(indent==0, "", paste0(rep(" ", indent), collapse = ""))
msg = paste0(tab, msg)
if (is.character(fn_name)) {
color_fn = crayon::silver
fn_name = sprintf("%s %s%s", color_fn(bold("<fn:")), red(paste0(fn_name)), color_fn(">"))
msg = paste(fn_name, msg)
}
if (timestamp) {
ts = cyan(paste0(Sys.time(), " "))
msg = paste0(ts, msg)
}
cat(sprintf(msg, ...), "\n")
if (sleep > 0) { Sys.sleep(sleep) }
if (abort) {
stop_quietly <- function() {
opt <- options(show.error.messages = FALSE)
on.exit(options(opt))
stop()
}
stop_quietly()
}
# Notify with macos_notify() if specified
if (notify) {
if (exists("macos_notify")) {
# Assign default values if only partial notification elements supplied
# Ex. If a user supplies notification = list(title = "test title"), then all other
# notification elements (subtitle, app_icon, ...) will be NULL. Assign these NULL
# values to default.
notification$title = ifelse(is.null(notification$title), "", notification$title)
notification$subtitle = ifelse(is.null(notification$subtitle), NA, notification$subtitle)
notification$app_icon = ifelse(is.null(notification$app_icon), NA, notification$app_icon)
notification$content_image = ifelse(is.null(notification$content_image), NA, notification$content_image)
notification$command = ifelse(is.null(notification$command), NA, notification$command)
notification$open_iterm = ifelse(is.null(notification$open_iterm), FALSE, notification$open_iterm)
macos_notify(
title = notification$title,
subtitle = notification$subtitle,
message = msg_raw,
app_icon = notification$app_icon,
content_image = notification$content_image,
command = notification$command,
open_iterm = notification$open_iterm)
} else {
stop("'notify' parameter is TRUE but macos_notify() function can't be found!")
}
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.