# Copyright 2010-2015 Meik Michalke <meik.michalke@hhu.de>
#
# This file is part of the R package rkwarddev.
#
# rkwarddev is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# rkwarddev is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with rkwarddev. If not, see <http://www.gnu.org/licenses/>.
#' Create JavaScript saveobject code from plugin XML
#'
#' @param pXML Either an object of class \code{XiMpLe.doc} or \code{XiMpLe.node}, or path to a plugin XML file.
#' @param R.objects Character vector, the names of the internal R objects to be saved. If not empty must have
#' the same length as <saveobject> nodes in the document, or be the keyword "initial", in which case the
#' \code{intital} attribute values of the nodes are used.
#' @param vars Logocal, whether the variables needed should also be defined in the JavaScript code.
#' @param add.abbrev Logical, if \code{TRUE} the JavaScript variables will all have a prefix with an
#' three letter abbreviation of the XML tag type to improve the readability of the code. But it's
#' probably better to add this in the XML code in the first place.
#' @param preview Logical, whether to prepare the JS code to be used in plugins with preview functionality, i.e.,
#' do not save objects while preview is active.
#' @param indent.by Character string used to indent each entry if \code{js=TRUE}.
#' @param level Integer, which indentation level to use, minimum is 1.
#' @return A character vector.
#' @seealso \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
#' @export
rk.JS.saveobj <- function(pXML, R.objects="initial", vars=TRUE, add.abbrev=FALSE, preview=FALSE, indent.by=rk.get.indent(), level=2){
single.tags <- get.single.tags(XML.obj=pXML, drop=c("comments","cdata", "declarations", "doctype"))
if(isTRUE(preview)){
main.level <- level + 1
} else {
main.level <- level
}
main.indent <- indent(main.level, by=indent.by)
# filter for relevant tags
cleaned.tags <- list()
for(this.tag in child.list(single.tags)){
this.tag.name <- tolower(XiMpLe:::XML.tagName(this.tag))
# we're only interested in entries with an ID
if(identical(this.tag.name, "saveobject")){
if("id" %in% names(XiMpLe:::parseXMLAttr(this.tag))){
cleaned.tags[length(cleaned.tags)+1] <- this.tag
} else {}
} else {}
}
num.tags <- length(cleaned.tags)
if(!is.null(R.objects)){
num.obj <- length(R.objects)
if(num.obj != num.tags & !identical(R.objects, "initial")){
stop(simpleError(paste0("Length of 'R.objects' (",num.obj,") is unequal to saveobject nodes found:\n ",
paste(unlist(cleaned.tags), collapse="\n "))))
} else {}
} else {}
if(length(cleaned.tags) > 0){
if(isTRUE(vars)){
JS.vars <- paste(unlist(sapply(1:num.tags, function(this.tagnum){
this.tag <- cleaned.tags[this.tagnum]
if(XiMpLe:::parseXMLAttr(this.tag)[["checkable"]] %in% c("T", "true", "TRUE", "1")){
modifiers=c("active", "parent")
} else {
modifiers="parent"
}
JS.id <- get.IDs(single.tags=this.tag, relevant.tags="saveobject", add.abbrev=add.abbrev)
return(rk.paste.JS(get.JS.vars(
JS.var=JS.id[1,"abbrev"],
XML.var=JS.id[1,"id"],
modifiers=as.list(modifiers),
default=TRUE),
level=main.level,
indent.by=indent.by))
})), collapse="")
# clean up: remove empty elements
JS.vars <- JS.vars[!grepl("^[[:space:]]*$", JS.vars)]
} else {
JS.vars <- NULL
}
JS.assign <- paste(unlist(sapply(1:num.tags, function(this.tagnum){
this.tag <- cleaned.tags[this.tagnum]
JS.id <- get.IDs(single.tags=this.tag, relevant.tags="saveobject", add.abbrev=add.abbrev)
JS.var <- camelCode(JS.id[1,"abbrev"])
JS.var.parent <- camelCode(c(JS.id[1,"abbrev"], "parent"))
if(is.null(R.objects)){
this.obj <- "REPLACE.ME.obj"
} else {
if(identical(R.objects, "initial")){
this.obj <- XiMpLe:::parseXMLAttr(this.tag)[["initial"]]
} else {
this.obj <- R.objects[this.tagnum]
}
}
# this can't be done by echo() because of the substitution
echo.code <- id("echo(\".GlobalEnv$\" + ", JS.var, " + \" <- ", this.obj, "\\n\");")
if(XiMpLe:::parseXMLAttr(this.tag)[["checkable"]] %in% c("T", "true", "TRUE", "1")){
JS.var.active <- camelCode(c(JS.id[1,"abbrev"], "active"))
JS.code <- ite(JS.var.active, echo.code)
} else {
JS.code <- echo.code
}
return(rk.paste.JS(JS.code, level=main.level, indent.by=indent.by))
})), collapse="\n")
results <- paste0(main.indent, "//// save result object\n",
if(!is.null(JS.vars)) {
paste0(main.indent, "// read in saveobject variables\n", JS.vars, "\n")
} else {}, main.indent, "// assign object to chosen environment\n", JS.assign
)
if(isTRUE(preview)){
results <- rk.paste.JS(
js(
if("!is_preview"){
results
} else {}
),
level=level
)
} else {}
return(results)
} else {
return(invisible(NULL))
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.