# Copyright 2010-2014 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 XML document for RKWard plugins
#'
#' @param name Character string, the name of the plugin. Will be used for the names of the JavaScript and
#' help files to be included, following the scheme \emph{"<name>.<ext>"}.
#' @param dialog An object of class \code{XiMpLe.node} to be pasted as the \code{<dialog>} section. See
#' \code{\link[rkwarddev:rk.XML.dialog]{rk.XML.dialog}} for details.
#' @param wizard An object of class \code{XiMpLe.node} to be pasted as the \code{<wizard>} section. See
#' \code{\link[rkwarddev:rk.XML.wizard]{rk.XML.wizard}} for details.
#' @param logic An object of class \code{XiMpLe.node} to be pasted as the \code{<logic>} section. See
#' \code{\link[rkwarddev:rk.XML.logic]{rk.XML.logic}} for details.
#' @param snippets An object of class \code{XiMpLe.node} to be pasted as the \code{<snippets>} section. See
#' \code{\link[rkwarddev:rk.XML.snippets]{rk.XML.snippets}} for details.
#' @param provides Character vector with possible entries of \code{"logic"}, \code{"dialog"} or \code{"wizard"}, defining what
#' sections the document should provide even if \code{dialog}, \code{wizard} and \code{logic} are \code{NULL}.
#' These sections must be edited manually and some parts are therefore commented out.
#' @param help Logical, if \code{TRUE} an include tag for a help file named \emph{"<name>.rkh"} will be added to the header.
#' @param include Character string or vector, relative path(s) to other file(s), which will then be included in the head of the GUI XML document.
#' @param label Character string, a text label for the plugin's top level, i.e. the window title of the dialog.
#' Will only be used if \code{dialog} or \code{wizard} are \code{NULL}.
#' @param clean.name Logical, if \code{TRUE}, all non-alphanumeric characters except the underscore (\code{"_"}) will be removed from \code{name}.
#' @param about An object of class \code{XiMpLe.node} with descriptive information on the plugin and its authors,
#' see \code{link[XiMpLe:rk.XML.about]{rk.XML.about}} for details. Only useful for information that differs from the \code{<about>}
#' section of the \code{.pluginmap} file. Skipped if \code{NULL}.
#' @param dependencies An object of class \code{XiMpLe.node} to be pasted as the \code{<dependencies>} section,
#' See \code{\link[rkwarddev:rk.XML.dependencies]{rk.XML.dependencies}} for details. Skipped if \code{NULL}.
#' This is only useful for information that differs from the \code{<dependencies>} section of the \code{.pluginmap} file.
#' @param gen.info Logical, if \code{TRUE} a comment note will be written into the document,
#' that it was generated by \code{rkwarddev} and changes should be done to the script.
#' You can also provide a character string naming the very rkwarddev script file that generates this plugin,
#' which will then also be added to the comment.
#' @param i18n Either a character string or a named list with the optional elements \code{context}
#' or \code{comment}, to give some \code{i18n_context} information for this node. If set to \code{FALSE},
#' the attribute \code{label} will be renamed into \code{noi18n_label}.
#' @return An object of class \code{XiMpLe.doc}.
#' @export
#' @seealso \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
#' @examples
#' \dontrun{
#' test.checkboxes <- rk.XML.row(rk.XML.col(
#' list(
#' rk.XML.cbox(label="foo", val="foo1", chk=TRUE),
#' rk.XML.cbox(label="bar", val="bar2"))))
#' test.dropdown <- rk.XML.dropdown("mydrop",
#' options=list("First Option"=c(val="val1"),
#' "Second Option"=c(val="val2", chk=TRUE)))
#' # combine the above into a tabbook
#' test.tabbook <- rk.XML.tabbook("My Tabbook", tabs=c(
#' "First Tab"=test.checkboxes, "Second Tab"=test.dropdown))
#' # make a plugin with that tabbook
#' test.plugin <- rk.XML.plugin("My test", dialog=rk.XML.dialog(test.tabbook))
#' }
rk.XML.plugin <- function(name, dialog=NULL, wizard=NULL, logic=NULL, snippets=NULL, provides=NULL, help=TRUE, include=NULL,
label=NULL, clean.name=TRUE, about=NULL, dependencies=NULL, gen.info=TRUE, i18n=NULL){
if(isTRUE(clean.name)){
name.orig <- name
name <- clean.name(name)
} else {}
all.children <- list()
if(isTRUE(gen.info)){
all.children[[length(all.children)+1]] <- generator.info()
} else if(is.character(gen.info)){
all.children[[length(all.children)+1]] <- generator.info(script=gen.info)
} else {}
all.children[[length(all.children)+1]] <- rk.XML.code(file=paste0(name, ".js"))
if(isTRUE(help)){
all.children[[length(all.children)+1]] <- rk.XML.help(file=paste0(name, ".rkh"))
} else {}
if(!is.null(include)){
for (thisInclude in include) {
all.children[[length(all.children)+1]] <- rk.XML.include(file=thisInclude)
}
} else {}
# check about and dependencies
# result is a named list with "about" and "dependencies"
about.dep.list <- dependenciesCompatWrapper(dependencies=dependencies, about=about, hints=FALSE)
dependencies <- about.dep.list[["dependencies"]]
about <- about.dep.list[["about"]]
# dependencies section
if(!is.null(dependencies)){
all.children[[length(all.children)+1]] <- dependencies
} else {}
# about section
if(!is.null(about)){
all.children[[length(all.children)+1]] <- about
} else {}
if(!is.null(snippets)){
# check if this is *really* a snippets section, otherwise quit and go dancing
valid.parent("snippets", node=snippets, see="rk.XML.snippets")
all.children[[length(all.children)+1]] <- snippets
} else {}
if(is.null(logic)){
if("logic" %in% provides){
lgc.children <- list(
# add these as comments because they need editing
XMLNode("!--", rk.XML.convert(sources="!edit!", mode=c(equals="!edit!"), id.name="!edit!")),
XMLNode("!--", rk.XML.connect(governor="!edit!", client="!edit!"))
)
all.children[[length(all.children)+1]] <- XMLNode("logic", .children=lgc.children)
} else {}
} else {
# check if this is *really* a logic section, otherwise quit and go dancing
valid.parent("logic", node=logic, see="rk.XML.logic")
all.children[[length(all.children)+1]] <- logic
}
if(is.null(dialog)){
if("dialog" %in% provides){
all.children[[length(all.children)+1]] <- rk.XML.dialog(label=label)
} else {}
} else {
# check if this is *really* a dialog section
valid.parent("dialog", node=dialog, see="rk.XML.dialog")
all.children[[length(all.children)+1]] <- dialog
}
if(is.null(wizard)){
if("wizard" %in% provides){
# create a first page for the wizard section
plugin.wizard.page <- rk.XML.page(id.name=auto.ids(label, prefix=ID.prefix("page")))
plugin.wizard <- rk.XML.wizard(plugin.wizard.page, label=label)
all.children[[length(all.children)+1]] <- plugin.wizard
} else {}
} else {
# check if this is *really* a wizard section
valid.parent("wizard", node=wizard, see="rk.XML.wizard")
all.children[[length(all.children)+1]] <- wizard
}
# check for additional i18n info; if FALSE, "label" will be renamed to "noi18n_label"
i18n.attrs <- check.i18n(i18n=i18n)
top.doc <- check.i18n(
i18n=i18n,
node=XMLNode("document", attrs=i18n.attrs, .children=child.list(all.children)),
comment=TRUE
)
plugin <- XMLTree(
dtd=list(doctype="rkplugin"),
.children=child.list(top.doc)
)
# check for duplicate IDs
return(plugin)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.