diff --git a/NAMESPACE b/NAMESPACE index c37ce80f..d2c5896a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -11,6 +11,8 @@ export(onRender) export(onStaticRenderComplete) export(prependContent) export(saveWidget) +export(save_html2) +export(scaffoldSimpleWidget) export(scaffoldWidget) export(setWidgetIdSeed) export(shinyRenderWidget) diff --git a/R/scaffold.R b/R/scaffold.R index d31c3c1e..e7b399ae 100644 --- a/R/scaffold.R +++ b/R/scaffold.R @@ -98,7 +98,7 @@ addWidgetJS <- function(name, edit){ # # This function uses bower to install a javascript package along with # its dependencies. -installBowerPkg <- function(pkg){ +installBowerPkg <- function(pkg, simple = FALSE){ # check if bower is installed if (findBower() == ""){ stop( @@ -107,13 +107,17 @@ installBowerPkg <- function(pkg){ ) } #check if we are in the root directory of a package - if (!file.exists('DESCRIPTION')){ + if (!simple && !file.exists('DESCRIPTION')){ stop("You need to be in a package directory to run this!", - call. = F) + call. = F) } # set up .bowerrc to install packages to correct directory if (!file.exists('.bowerrc')){ - x = '{"directory": "inst/htmlwidgets/lib"}' + if (!simple){ + x = '{"directory": "inst/htmlwidgets/lib"}' + } else { + x = '{"directory": "htmlwidgets/lib"}' + } cat(x, file = '.bowerrc') } # Install package diff --git a/R/simplewidget.R b/R/simplewidget.R new file mode 100644 index 00000000..1db08c87 --- /dev/null +++ b/R/simplewidget.R @@ -0,0 +1,125 @@ +#' Scaffold simple widgets +#' +#' @export +scaffoldSimpleWidget <- function(name, bowerPkg = NULL, edit = interactive(), + dir_){ + if (!file.exists(dir_)){ + dir.create(dir_) + dir.create(file.path(dir_, 'htmlwidgets')) + cwd = getwd(); setwd(dir_); + } + dir_ = "." + package = normalizePath(dir_) + + tpl <- paste(readLines( + system.file('templates/widget_r.txt', package = 'htmlwidgets') + ), collapse = "\n") + + capName = function(name){ + paste0(toupper(substring(name, 1, 1)), substring(name, 2)) + } + if (!file.exists(file_ <- file.path(dir_, paste0(name, '.R')))){ + cat( + sprintf(tpl, name, name, package, name, name, name, name, name, name, + package, name, capName(name), name), + file = file_ + ) + message('Created boilerplate for widget constructor ', file_) + } else { + message(file_, " already exists") + } + if (edit) fileEdit(file_) + tpl <- "# (uncomment to add a dependency) + # dependencies: + # - name: + # version: + # src: + # script: + # stylesheet: + " + if (!is.null(bowerPkg)){ + installBowerPkg(bowerPkg, simple = TRUE) + tpl <- getConfig(bowerPkg, src = 'htmlwidgets/lib') + } + if (!file.exists(file_ <- sprintf('%s/htmlwidgets/%s.yaml', dir_, name))){ + cat(paste(tpl, "\n"), file = file_) + message('Created boilerplate for widget dependencies at ', + sprintf('%s/htmlwidgets/%s.yaml', dir_, name) + ) + } else { + message(file_, " already exists") + } + if (edit) fileEdit(file_) + + tpl <- paste(readLines( + system.file('templates/widget_js.txt', package = 'htmlwidgets') + ), collapse = "\n") + + if (!file.exists(file_ <- sprintf('%s/htmlwidgets/%s.js', dir_, name))){ + cat(sprintf(tpl, name), file = file_) + message('Created boilerplate for widget dependencies at ', + sprintf('%s/htmlwidgets/%s.js', dir_, name) + ) + } else { + message(file_, " already exists") + } + + if (!file.exists('index.R')){ + x = sprintf("source('%s.R')\nhtml <- %s('World')", name, name) + cat(x, file = file.path(dir_, "index.R")) + } + if (!file.exists("Makefile")){ + f <- system.file('templates/Makefile', package = 'htmlwidgets') + f2 <- gsub('hello', name, paste(readLines(f), collapse = '\n')) + cat(f2, file = file.path(dir_, 'Makefile')) + } + if (edit) fileEdit(file_) + if (edit){ + fileEdit('index.R') + servr::make() + } else { + on.exit(setwd(cwd)) + } +} + +#' Save simple widget html +#' +#' @export +save_html2 <- function (html, file = 'index.html', background = "white", libdir = "."){ + options(htmlwidgets.copybindingdir = FALSE) + on.exit(options(htmlwidgets.copybindingdir = TRUE)) + rendered <- renderTags(html) + deps <- lapply(rendered$dependencies, function(dep) { + dep <- if (dep$name == 'htmlwidgets'){ + dep <- copyDependencyToDir(dep, file.path(libdir, 'htmlwidgets'), FALSE) + dep <- makeDependencyRelative(dep, libdir, FALSE) + } else { + dep <- makeDependencyRelative(dep, libdir, FALSE) + } + dep + }) + html <- c("", "", "", "", + renderDependencies(deps, c("href", "file")), rendered$head, + " ", sprintf("", + htmlEscape(background)), rendered$html, "", + "" + ) + writeLines(html, file, useBytes = TRUE) +} + + +system_file <- function(..., package){ + if (file.exists(package)){ + file.path(package, ...) + } else { + system.file(..., package = package) + } +} + +binding_version <- function(package){ + if (file.exists(package)){ + '0.1' + } else { + packageVersion(package) + } +} diff --git a/R/utils.R b/R/utils.R index 4cd2a8a4..9b1784d8 100644 --- a/R/utils.R +++ b/R/utils.R @@ -46,14 +46,14 @@ getDependency <- function(name, package = name){ jsfile = sprintf("htmlwidgets/%s.js", name) config = yaml::yaml.load_file( - system.file(config, package = package) + system_file(config, package = package) ) widgetDep <- lapply(config$dependencies, function(l){ - l$src = system.file(l$src, package = package) + l$src = system_file(l$src, package = package) do.call(htmlDependency, l) }) - bindingDir <- system.file("htmlwidgets", package = package) + bindingDir <- system_file("htmlwidgets", package = package) argsDep <- NULL copyBindingDir <- getOption('htmlwidgets.copybindingdir', TRUE) # TODO: remove this trick when htmltools >= 0.3.3 is on CRAN @@ -61,11 +61,13 @@ getDependency <- function(name, package = name){ if (packageVersion('htmltools') < '0.3.3') { bindingDir <- tempfile("widgetbinding") dir.create(bindingDir, mode = "0700") - file.copy(system.file(jsfile, package = package), bindingDir) + file.copy(system_file(jsfile, package = package), bindingDir) } else argsDep <- list(all_files = FALSE) + } else { + bindingDir <- system_file("htmlwidgets", package = package) } bindingDep <- do.call(htmlDependency, c(list( - paste0(name, "-binding"), packageVersion(package), + paste0(name, "-binding"), binding_version(package), bindingDir, script = basename(jsfile) ), argsDep)) diff --git a/inst/templates/Makefile b/inst/templates/Makefile new file mode 100644 index 00000000..9bfa7810 --- /dev/null +++ b/inst/templates/Makefile @@ -0,0 +1,4 @@ +all: index.html + +index.html: htmlwidgets/hello.js hello.R index.R + Rscript -e "library(htmlwidgets); source('index.R'); save_html2(html)" diff --git a/man/save_html2.Rd b/man/save_html2.Rd new file mode 100644 index 00000000..3a7469fa --- /dev/null +++ b/man/save_html2.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/simplewidget.R +\name{save_html2} +\alias{save_html2} +\title{Save simple widget html} +\usage{ +save_html2(html, file = "index.html", background = "white", libdir = ".") +} +\description{ +Save simple widget html +} + diff --git a/man/scaffoldSimpleWidget.Rd b/man/scaffoldSimpleWidget.Rd new file mode 100644 index 00000000..71964787 --- /dev/null +++ b/man/scaffoldSimpleWidget.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/simplewidget.R +\name{scaffoldSimpleWidget} +\alias{scaffoldSimpleWidget} +\title{Scaffold simple widgets} +\usage{ +scaffoldSimpleWidget(name, bowerPkg = NULL, edit = interactive(), dir_) +} +\description{ +Scaffold simple widgets +} +