[rkward-cvs] SF.net SVN: rkward:[3978] trunk/rkward/packages/rkwarddev
m-eik at users.sourceforge.net
m-eik at users.sourceforge.net
Thu Oct 20 14:43:16 UTC 2011
Revision: 3978
http://rkward.svn.sourceforge.net/rkward/?rev=3978&view=rev
Author: m-eik
Date: 2011-10-20 14:43:15 +0000 (Thu, 20 Oct 2011)
Log Message:
-----------
rkwarddev: added support for more than one dialog/component to rk.plugin.skeleton()
Modified Paths:
--------------
trunk/rkward/packages/rkwarddev/ChangeLog
trunk/rkward/packages/rkwarddev/DESCRIPTION
trunk/rkward/packages/rkwarddev/NAMESPACE
trunk/rkward/packages/rkwarddev/R/rk-internal.R
trunk/rkward/packages/rkwarddev/R/rk.XML.plugin.R
trunk/rkward/packages/rkwarddev/R/rk.plugin.skeleton.R
trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R
trunk/rkward/packages/rkwarddev/inst/CITATION
trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.pdf
trunk/rkward/packages/rkwarddev/man/rk.XML.plugin.Rd
trunk/rkward/packages/rkwarddev/man/rk.plugin.skeleton.Rd
trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd
Added Paths:
-----------
trunk/rkward/packages/rkwarddev/R/rk.plug.comp-class.R
trunk/rkward/packages/rkwarddev/R/rk.plugin.component.R
trunk/rkward/packages/rkwarddev/man/rk.plugin.component.Rd
Modified: trunk/rkward/packages/rkwarddev/ChangeLog
===================================================================
--- trunk/rkward/packages/rkwarddev/ChangeLog 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/ChangeLog 2011-10-20 14:43:15 UTC (rev 3978)
@@ -1,5 +1,10 @@
ChangeLog for package rkwarddev
+## 0.04-1 (2011-10-20)
+ - added "about" option to rk.XML.plugin() to overrule pluginmap defaults
+ - added rk.plugin.component(), i.e. modularized the component generation, to allow for more than one
+ component in rk.plugin.skeleton(), wich subsequently gained the new option "components"
+
## 0.04-0 (2011-10-19)
- for accurcy and consistency with the docs, the "properties" option changed to "modifiers" in rk.JS.vars()
- added further property modifiers to the internal validation
Modified: trunk/rkward/packages/rkwarddev/DESCRIPTION
===================================================================
--- trunk/rkward/packages/rkwarddev/DESCRIPTION 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/DESCRIPTION 2011-10-20 14:43:15 UTC (rev 3978)
@@ -14,8 +14,8 @@
URL: http://rkward.sourceforge.net
Authors at R: c(person(given="Meik", family="Michalke",
email="meik.michalke at hhu.de", role=c("aut", "cre")))
-Version: 0.04-0
-Date: 2011-10-19
+Version: 0.04-1
+Date: 2011-10-20
Collate:
'echo.R'
'id.R'
@@ -34,9 +34,12 @@
'rk.JS.var-class.R'
'rk.JS.vars.R'
'rk.paste.JS.R'
+ 'rk.rkh.doc.R'
+ 'rk.XML.plugin.R'
+ 'rk.plug.comp-class.R'
+ 'rk.plugin.component.R'
'rk.plugin.skeleton.R'
'rk.rkh.caption.R'
- 'rk.rkh.doc.R'
'rk.rkh.link.R'
'rk.rkh.related.R'
'rk.rkh.scan.R'
@@ -78,7 +81,6 @@
'rk.XML.menu.R'
'rk.XML.page.R'
'rk.XML.pluginmap.R'
- 'rk.XML.plugin.R'
'rk.XML.preview.R'
'rk.XML.radio.R'
'rk.XML.require.R'
Modified: trunk/rkward/packages/rkwarddev/NAMESPACE
===================================================================
--- trunk/rkward/packages/rkwarddev/NAMESPACE 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/NAMESPACE 2011-10-20 14:43:15 UTC (rev 3978)
@@ -2,6 +2,7 @@
exportClasses(rk.JS.ite)
exportClasses(rk.JS.opt)
exportClasses(rk.JS.var)
+exportClasses(rk.plug.comp)
export(echo)
export(id)
export(ite)
@@ -15,6 +16,7 @@
export(rk.JS.scan)
export(rk.JS.vars)
export(rk.paste.JS)
+export(rk.plugin.component)
export(rk.plugin.skeleton)
export(rk.rkh.caption)
export(rk.rkh.doc)
Modified: trunk/rkward/packages/rkwarddev/R/rk-internal.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk-internal.R 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/R/rk-internal.R 2011-10-20 14:43:15 UTC (rev 3978)
@@ -12,6 +12,7 @@
return(ids)
} ## end function auto.ids()
+
## function child.list()
# convenience function to let single children be provided without list()
child.list <- function(children){
@@ -28,6 +29,7 @@
return(children)
} ## end function child.list()
+
## function trim()
# cuts off space at start and end of a character string
trim <- function(char){
@@ -36,12 +38,26 @@
return(char)
} ## end function trim()
+
## function indent()
# will create tabs to format the output
indent <- function(level, by="\t"){
paste(rep(by, level-1), collapse="")
} ## end function indent()
+
+## function checkCreateFiles()
+# used by rk.plugin.skeleton()
+checkCreateFiles <- function(file.name, ow){
+ if(all(file.exists(file.name), as.logical(ow)) | !file.exists(file.name)){
+ return(TRUE)
+ } else {
+ warning(paste("Skipping existing file ", file.name, ".", sep=""))
+ return(FALSE)
+ }
+} ## end function checkCreateFiles()
+
+
## function get.single.tags()
get.single.tags <- function(XML.obj, drop=NULL){
# determine if we need to read a file or process an XiMpLe object
@@ -118,6 +134,7 @@
return(ids)
} ## end function get.IDs()
+
## function camelCode()
# changes the first letter of each string
# (except for the first one) to upper case
@@ -139,6 +156,7 @@
return(results)
} ## end function camelCode()
+
## function get.JS.vars()
# <tag id="my.id" ...>
# in XML will become
@@ -204,6 +222,7 @@
return(results)
} ## end function get.JS.vars()
+
## function ID.prefix()
ID.prefix <- function(initial, abbr=TRUE, length=3, dot=FALSE){
if(isTRUE(abbr)){
@@ -220,6 +239,7 @@
return(prfx)
} ## end function ID.prefix()
+
## function node.soup()
# pastes the nodes as XML, only alphanumeric characters, e.g. to generate auto-IDs
node.soup <- function(nodes){
@@ -233,6 +253,7 @@
return(the.soup)
} ## end function node.soup()
+
## function XML2person()
# extracts the person/author info from XML "about" nodes
XML2person <- function(node, eval=FALSE){
@@ -273,6 +294,7 @@
return(all.authors)
} ## end function XML2person()
+
## function get.by.role()
# filters a vector with person objects by roles
get.by.role <- function(persons, role="aut"){
@@ -281,6 +303,7 @@
return(filtered.persons)
} ## end function get.by.role()
+
## function check.ID()
check.ID <- function(node){
if(is.list(node)){
@@ -304,6 +327,7 @@
return(node.ID)
} ## end function check.ID()
+
## list with valid modifiers
all.valid.modifiers <- list(
all=c("visible", "enabled", "required", "true", "false", "not", "numeric",
@@ -325,6 +349,7 @@
preview=c("state")
) ## end list with valid modifiers
+
## function modif.validity()
# checks if a modifier is valid for an XML node, if source is XiMpLe.node
# if bool=FALSE, returns the modifier or ""
@@ -380,6 +405,7 @@
}
} ## end function modif.validity()
+
## function check.type()
check.type <- function(value, type, var.name, warn.only=TRUE){
if(inherits(value, type)){
@@ -394,6 +420,7 @@
}
} ## end function check.type()
+
## function clean.name()
clean.name <- function(name, message=TRUE){
name.orig <- name
@@ -406,6 +433,7 @@
return(name)
} ## end function clean.name()
+
## function paste.JS.ite()
paste.JS.ite <- function(object, level=1, indent.by="\t", recurse=FALSE){
stopifnot(inherits(object, "rk.JS.ite"))
@@ -436,6 +464,7 @@
return(result)
} ## end function paste.JS.ite()
+
## function paste.JS.array()
paste.JS.array <- function(object, level=2, indent.by="\t", funct=NULL){
stopifnot(inherits(object, "rk.JS.arr"))
@@ -480,6 +509,7 @@
return(JS.array)
} ## end function paste.JS.array()
+
## function paste.JS.options()
paste.JS.options <- function(object, level=2, indent.by="\t", array=NULL, funct=NULL){
stopifnot(inherits(object, "rk.JS.opt"))
@@ -565,6 +595,7 @@
return(JS.options)
} ## end function paste.JS.options()
+
## function paste.JS.var()
paste.JS.var <- function(object, level=2, indent.by="\t", JS.prefix=NULL, modifiers=NULL, default=NULL, join=NULL, names.only=FALSE){
# paste several objects
Modified: trunk/rkward/packages/rkwarddev/R/rk.XML.plugin.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.XML.plugin.R 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/R/rk.XML.plugin.R 2011-10-20 14:43:15 UTC (rev 3978)
@@ -18,6 +18,9 @@
#' @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, its authors and dependencies,
+#' 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}.
#' @return An object of class \code{XiMpLe.doc}.
#' @export
#' @seealso \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
@@ -36,7 +39,7 @@
#' test.plugin <- rk.XML.plugin("My test", dialog=test.tabbook)
#' cat(pasteXMLTree(test.plugin))
-rk.XML.plugin <- function(name, dialog=NULL, wizard=NULL, logic=NULL, snippets=NULL, provides=NULL, help=TRUE, pluginmap=NULL, label=NULL, clean.name=TRUE){
+rk.XML.plugin <- function(name, dialog=NULL, wizard=NULL, logic=NULL, snippets=NULL, provides=NULL, help=TRUE, pluginmap=NULL, label=NULL, clean.name=TRUE, about=NULL){
if(isTRUE(clean.name)){
name.orig <- name
name <- clean.name(name)
@@ -52,6 +55,20 @@
all.children[[length(all.children)+1]] <- rk.XML.include(file=pluginmap)
} else {}
+ if(!is.null(about)){
+ if(inherits(about, "XiMpLe.node")){
+ about.node.name <- about at name
+ # check if this is *really* a about section, otherwise quit and go dancing
+ if(!identical(about.node.name, "about")){
+ stop(simpleError("I don't know what this is, but 'about' is not an about section!"))
+ } else {
+ all.children[[length(all.children)+1]] <- about
+ }
+ } else {
+ stop(simpleError("'about' must be a XiMpLe.node, see ?rk.XML.about()!"))
+ }
+ } else {}
+
if(!is.null(snippets)){
# check if this is *really* a snippets section, otherwise quit and go dancing
if(inherits(snippets, "XiMpLe.node")){
Added: trunk/rkward/packages/rkwarddev/R/rk.plug.comp-class.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.plug.comp-class.R (rev 0)
+++ trunk/rkward/packages/rkwarddev/R/rk.plug.comp-class.R 2011-10-20 14:43:15 UTC (rev 3978)
@@ -0,0 +1,30 @@
+#' @include rk.XML.plugin.R
+#' @include rk.JS.doc.R
+#' @include rk.rkh.doc.R
+#' @export
+
+# this class holds plugin components, i.e. single dialogs, to add to a plugin skeleton
+# produced by rk.plugin.component()
+
+setClass("rk.plug.comp",
+ representation=representation(
+ name="character",
+ create="vector",
+ xml="XiMpLe.doc",
+ js="character",
+ rkh="XiMpLe.doc",
+ hierarchy="list"
+ ),
+ prototype(
+ name=character(),
+ create=c(),
+ xml=new("XiMpLe.doc"),
+ js=character(),
+ rkh=new("XiMpLe.doc"),
+ hierarchy=list()
+ )
+)
+
+# setValidity("rk.plug.comp", function(object){
+# return(TRUE)
+# })
Added: trunk/rkward/packages/rkwarddev/R/rk.plugin.component.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.plugin.component.R (rev 0)
+++ trunk/rkward/packages/rkwarddev/R/rk.plugin.component.R 2011-10-20 14:43:15 UTC (rev 3978)
@@ -0,0 +1,194 @@
+#' Generate RKWard plugin components
+#'
+#' @param name Character sting, name of this plugin component.
+#' @param about An object of class \code{XiMpLe.node} with descriptive information on the plugin, its authors and dependencies,
+#' 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 xml A named list of options to be forwarded to \code{\link[rkwarddev:rk.XML.plugin]{rk.XML.plugin}}, to generate the GUI XML file.
+#' Not all options are supported because some don't make sense in this context. Valid options are:
+#' \code{"dialog"}, \code{"wizard"}, \code{"logic"} and \code{"snippets"}.
+#' If not set, their default values are used. See \code{\link[rkwarddev:rk.XML.plugin]{rk.XML.plugin}} for details.
+#' @param js A named list of options to be forwarded to \code{\link[rkwarddev:rk.JS.doc]{rk.JS.doc}}, to generate the JavaScript file.
+#' Not all options are supported because some don't make sense in this context. Valid options are:
+#' \code{"require"}, \code{"results.header"}, \code{"variables"}, \code{"preprocess"}, \code{"calculate"} and \code{"printout"}.
+#' If not set, their default values are used. See \code{\link[rkwarddev:rk.JS.doc]{rk.JS.doc}} for details.
+#' @param rkh A named list of options to be forwarded to \code{\link[rkwarddev:rk.rkh.doc]{rk.rkh.doc}}, to generate the help file.
+#' Not all options are supported because some don't make sense in this context. Valid options are:
+#' \code{"summary"}, \code{"usage"}, \code{"sections"}, \code{"settings"}, \code{"related"} and \code{"technical"}.
+#' If not set, their default values are used. See \code{\link[rkwarddev:rk.rkh.doc]{rk.rkh.doc}} for details.
+#' @param provides Character vector with possible entries of \code{"logic"}, \code{"dialog"} or \code{"wizard"}, defining what
+#' sections the GUI XML file 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 scan A character vector to trigger various automatic scans of the generated GUI XML file. Valid enties are:
+#' \describe{
+#' \item{\code{"var"}}{Calls \code{\link{rk.JS.scan}} to define all needed variables in the \code{calculate()} function
+#' of the JavaScript file. These variables will be added to variables defined by the \code{js} option, if any (see below).}
+#' \item{\code{"saveobj"}}{Calls \code{\link{rk.JS.saveobj}} to generate code to save R results in the \code{printout()}
+#' function of the JavaScript file. This code will be added to the code defined by the \code{js} option, if any (see below).}
+#' \item{\code{"settings"}}{Calls \code{\link{rk.rkh.scan}} to generate \code{<setting>} sections for each relevant GUI element in
+#' the \code{<settings>} section of the help file. This option will be overruled if you provide that section manually
+#' by the \code{rkh} option (see below).}
+#' }
+#' @param hierarchy A character vector with instructions where to place this component in the menu hierarchy, one list or string.
+#' Valid single values are \code{"file"}, \code{"edit"}, \code{"view"}, \code{"workspace"}, \code{"run"}, \code{"data"},
+#' \code{"analysis"}, \code{"plots"}, \code{"distributions"}, \code{"windows"}, \code{"settings"} and \code{"help"},
+#' anything else will place it in a "test" menu. If \code{hierarchy} is a list, each entry represents the label of a menu level.
+#' @param pluginmap Character string, relative path to the pluginmap file, which will then be included in the head of the GUI XML document.
+#' @param create A character vector with one or more of these possible entries:
+#' \describe{
+#' \item{\code{"xml"}}{Create the plugin \code{.xml} XML file skeleton.}
+#' \item{\code{"js"}}{Create the plugin \code{.js} JavaScript file skeleton.}
+#' \item{\code{"rkh"}}{Create the plugin \code{.rkh} help file skeleton.}
+#' }
+#' @param indent.by A character string defining the indentation string to use.
+#' @return An object of class \code{rk.plug.comp}.
+#' @seealso \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
+#' @export
+#' @examples
+#' \dontrun{
+#' test.dropdown <- rk.XML.dropdown("mydrop",
+#' opts=list("First Option"=c(val="val1"),
+#' "Second Option"=c(val="val2", chk=TRUE)))
+#' test.checkboxes <- rk.XML.row(rk.XML.col(
+#' list(test.dropdown,
+#' rk.XML.cbox(label="foo", val="foo1", chk=TRUE),
+#' rk.XML.cbox(label="bar", val="bar2"))
+#' ))
+#' test.vars <- rk.XML.vars("select some vars", "vars go here")
+#' test.tabbook <- rk.XML.dialog(rk.XML.tabbook("My Tabbook", tab.labels=c("First Tab",
+#' "Second Tab"), children=list(test.checkboxes, test.vars)))
+#'
+#' rk.plugin.component("Square the Circle",
+#' xml=list(dialog=test.tabbook))
+#' }
+
+rk.plugin.component <- function(name, about=NULL, xml=list(), js=list(), rkh=list(),
+ provides=c("logic", "dialog"), scan=c("var", "saveobj", "settings"), hierarchy="test",
+ pluginmap=NULL, create=c("xml", "js", "rkh"), indent.by="\t"){
+ # to besure, remove all non-character symbols from name
+ name.orig <- name
+ name <- clean.name(name)
+
+ if(!is.null(about)){
+ if(inherits(about, "XiMpLe.node")){
+ about.node.name <- about at name
+ # check if this is *really* a about section, otherwise quit and go dancing
+ if(!identical(about.node.name, "about")){
+ stop(simpleError("I don't know what this is, but 'about' is not an about section!"))
+ } else {
+ about.node <- about
+ }
+ } else {
+ stop(simpleError("'about' must be a XiMpLe.node, see ?rk.XML.about()!"))
+ }
+ } else {
+ about.node <- NULL
+ }
+
+ # check hierarchy
+ if(is.null(hierarchy)){
+ hierarchy <- list()
+ } else {
+ hierarchy <- as.list(hierarchy)
+ }
+
+ ## create the full component
+ this.component <- new("rk.plug.comp",
+ name=name.orig,
+ create=create,
+ hierarchy=hierarchy
+ )
+
+ ## create plugin.xml
+ if("xml" %in% create & length(xml) > 0){
+ got.XML.options <- names(xml)
+ for (this.opt in c("dialog", "wizard", "logic", "snippets")){
+ if(!this.opt %in% got.XML.options) {
+ xml[[this.opt]] <- eval(formals(rk.XML.plugin)[[this.opt]])
+ } else {}
+ }
+ XML.plugin <- rk.XML.plugin(
+ name=name,
+ label=name.orig,
+ dialog=xml[["dialog"]],
+ wizard=xml[["wizard"]],
+ logic=xml[["logic"]],
+ snippets=xml[["snippets"]],
+ provides=provides,
+ pluginmap=pluginmap,
+ about=about.node)
+ this.component at xml <- XML.plugin
+ } else {
+ this.component at xml <- rk.XML.plugin("")
+ }
+
+ ## create plugin.js
+ if("js" %in% create & length(js) > 0){
+ got.JS.options <- names(js)
+ for (this.opt in c("require", "variables", "preprocess", "calculate", "printout")){
+ if(!this.opt %in% got.JS.options) {
+ js[[this.opt]] <- eval(formals(rk.JS.doc)[[this.opt]])
+ } else {}
+ }
+ if(!"results.header" %in% got.JS.options) {
+ js[["results.header"]] <- paste(name.orig, " results", sep="")
+ } else {}
+ if("var" %in% scan){
+ var.scanned <- rk.JS.scan(XML.plugin)
+ if(!is.null(var.scanned)){
+ js[["variables"]] <- paste(
+ ifelse(is.null(js[["variables"]]), "", paste(js[["variables"]], "\n", sep="")),
+ var.scanned,
+ sep="")
+ } else {}
+ } else {}
+ if("saveobj" %in% scan){
+ saveobj.scanned <- rk.JS.saveobj(XML.plugin)
+ if(!is.null(saveobj.scanned)){
+ js[["printout"]] <- paste(js[["printout"]], saveobj.scanned, sep="\n")
+ } else {}
+ } else {}
+ JS.code <- rk.JS.doc(
+ require=js[["require"]],
+ variables=js[["variables"]],
+ results.header=js[["results.header"]],
+ preprocess=js[["preprocess"]],
+ calculate=js[["calculate"]],
+ printout=js[["printout"]],
+ indent.by=indent.by)
+ this.component at js <- JS.code
+ } else {
+ this.component at js <- rk.JS.doc()
+ }
+
+ ## create plugin.rkh
+ if("rkh" %in% create & length(rkh) > 0){
+ got.rkh.options <- names(rkh)
+ # if settings were defined manually, this overwrites the scan
+ if(!"settings" %in% got.rkh.options){
+ if("settings" %in% scan){
+ rkh[["settings"]] <- rk.rkh.settings(rk.rkh.scan(XML.plugin))
+ } else {
+ rkh[["settings"]] <- eval(formals(rk.rkh.doc)[["settings"]])
+ }
+ } else {}
+ for (this.opt in c("summary", "usage", "sections", "related", "technical")){
+ if(!this.opt %in% got.rkh.options) {
+ rkh[[this.opt]] <- eval(formals(rk.rkh.doc)[[this.opt]])
+ } else {}
+ }
+ rkh.doc <- rk.rkh.doc(
+ summary=rkh[["summary"]],
+ usage=rkh[["usage"]],
+ sections=rkh[["sections"]],
+ settings=rkh[["settings"]],
+ related=rkh[["related"]],
+ technical=rkh[["technical"]],
+ title=rk.rkh.title(name.orig))
+ this.component at rkh <- rkh.doc
+ } else {
+ this.component at rkh <- rk.rkh.doc()
+ }
+
+ return(this.component)
+}
Modified: trunk/rkward/packages/rkwarddev/R/rk.plugin.skeleton.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.plugin.skeleton.R 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/R/rk.plugin.skeleton.R 2011-10-20 14:43:15 UTC (rev 3978)
@@ -1,4 +1,8 @@
#' Generate skeletons for RKWard plugins
+#'
+#' With this function you can write everything from a basic skeleton structure to a complete functional plugin, including several
+#' components/dialogs. You should always define one main component (by \code{xml}, \code{js}, \code{rkh} etc.) before you provide
+#' additional features by \code{components}.
#'
#' @param name Character sting, name of the plugin package.
#' @param about An object of class \code{XiMpLe.node} with descriptive information on the plugin, its authors and dependencies,
@@ -53,7 +57,7 @@
#' @param load Logical, if \code{TRUE} and \code{"pmap"} in \code{create}, RKWard will automatically add the created .pluginmap file
#' to its menu structure by calling \code{rk.load.pluginmaps}. You can then try the plugin immediately.
#' @param show Logical, if \code{TRUE} and \code{"pmap"} in \code{create}, RKWard will automatically call the created plugin after
-#' it was loaded (i.e., this implies and also sets \code{load=TRUE}).
+#' it was loaded (i.e., this implies and also sets \code{load=TRUE}). This will only work on the main component, though.
#' @param indent.by A character string defining the indentation string to use.
#' @return Character string with the path to the plugin root directory.
#' @seealso \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
@@ -123,7 +127,7 @@
xml=list(), js=list(), pluginmap=list(), rkh=list(),
overwrite=FALSE, tests=TRUE, lazyLoad=TRUE,
create=c("pmap", "xml", "js", "rkh", "desc"),
- edit=FALSE, load=FALSE, show=FALSE, indent.by="\t"){
+ components=list(), edit=FALSE, load=FALSE, show=FALSE, indent.by="\t"){
# to besure, remove all non-character symbols from name
name.orig <- name
name <- clean.name(name)
@@ -153,27 +157,12 @@
plugin.dir <- file.path(rkward.dir, "plugins")
# the basic file names
plugin.fname.pluginmap <- paste(name, ".pluginmap", sep="")
- plugin.fname.xml <- paste(name, ".xml", sep="")
- plugin.fname.js <- paste(name, ".js", sep="")
- plugin.fname.rkh <- paste(name, ".rkh", sep="")
# file names with paths
plugin.pluginmap <- file.path(rkward.dir, plugin.fname.pluginmap)
- plugin.xml <- file.path(plugin.dir, plugin.fname.xml)
- plugin.js <- file.path(plugin.dir, plugin.fname.js)
- plugin.rkh <- file.path(plugin.dir, plugin.fname.rkh)
tests.main.dir <- file.path(rkward.dir, "tests")
tests.dir <- file.path(rkward.dir, "tests", name)
testsuite.file <- file.path(tests.main.dir, "testsuite.R")
- checkCreateFiles <- function(file.name, ow=overwrite){
- if(all(file.exists(file.name), as.logical(ow)) | !file.exists(file.name)){
- return(TRUE)
- } else {
- warning(paste("Skipping existing file ", file.name, ".", sep=""))
- return(FALSE)
- }
- }
-
# check if we can access the given root directory
# create it, if necessary
if(!file_test("-d", main.dir)){
@@ -191,127 +180,97 @@
message(paste("Created directory ", tests.dir, ".", sep=""))
} else {}
- ## create plugin.xml
- if("xml" %in% create){
- if(isTRUE(checkCreateFiles(plugin.xml))){
- got.XML.options <- names(xml)
- for (this.opt in c("dialog", "wizard", "logic", "snippets")){
- if(!this.opt %in% got.XML.options) {
- xml[[this.opt]] <- eval(formals(rk.XML.plugin)[[this.opt]])
- } else {}
- }
- XML.plugin <- rk.XML.plugin(
- name=name,
- label=name.orig,
- dialog=xml[["dialog"]],
- wizard=xml[["wizard"]],
- logic=xml[["logic"]],
- snippets=xml[["snippets"]],
- provides=provides,
- pluginmap=paste("../", name, ".pluginmap", sep=""))
- cat(pasteXMLTree(XML.plugin, shine=1, indent.by=indent.by), file=plugin.xml)
- } else {
- # set a variable for the other sections to use as XML input
- XML.plugin <- plugin.xml
- }
- if(isTRUE(edit)){
- rk.edit.files(plugin.xml, title=plugin.fname.xml, prompt=FALSE)
- } else {}
+ ## create the main component
+ got.pm.options <- names(pluginmap)
+ if(!"hierarchy" %in% got.pm.options) {
+ pluginmap[["hierarchy"]] <- eval(formals(rk.XML.pluginmap)[["hierarchy"]])
} else {}
+ main.component <- rk.plugin.component(
+ name=name.orig,
+ xml=xml,
+ js=js,
+ rkh=rkh,
+ provides=provides,
+ scan=scan,
+ hierarchy=pluginmap[["hierarchy"]],
+ pluginmap=paste("../", name, ".pluginmap", sep=""),
+ create=create[create %in% c("xml", "js", "rkh")],
+ indent.by=indent.by)
+ components[[length(components)+1]] <- main.component
- ## create plugin.js
- if("js" %in% create){
- if(isTRUE(checkCreateFiles(plugin.js))){
- # require=c(), variables=NULL, preprocess=NULL, calculate=NULL, printout=NULL, results.header=NULL
- got.JS.options <- names(js)
- for (this.opt in c("require", "variables", "preprocess", "calculate", "printout")){
- if(!this.opt %in% got.JS.options) {
- js[[this.opt]] <- eval(formals(rk.JS.doc)[[this.opt]])
+ # check for components
+ sapply(components, function(this.comp){
+ if(!inherits(this.comp, "rk.plug.comp")){
+ warning("An element of list 'components' was not of class rk.plug.comp and ignored!", call.=FALSE)
+ } else {
+ comp.name <- clean.name(this.comp at name)
+ create <- this.comp at create
+ XML.plugin <- this.comp at xml
+ JS.code <- this.comp at js
+ rkh.doc <- this.comp at rkh
+
+ # the basic file names
+ plugin.fname.xml <- paste(comp.name, ".xml", sep="")
+ plugin.fname.js <- paste(comp.name, ".js", sep="")
+ plugin.fname.rkh <- paste(comp.name, ".rkh", sep="")
+ # file names with paths
+ plugin.xml <- file.path(plugin.dir, plugin.fname.xml)
+ plugin.js <- file.path(plugin.dir, plugin.fname.js)
+ plugin.rkh <- file.path(plugin.dir, plugin.fname.rkh)
+
+ ## create plugin.xml
+ if("xml" %in% create){
+ if(isTRUE(checkCreateFiles(plugin.xml, ow=overwrite))){
+ cat(pasteXMLTree(XML.plugin, shine=1, indent.by=indent.by), file=plugin.xml)
} else {}
- }
- if(!"results.header" %in% got.JS.options) {
- js[["results.header"]] <- paste(name.orig, " results", sep="")
- } else {}
- if("var" %in% scan){
- var.scanned <- rk.JS.scan(XML.plugin)
- if(!is.null(var.scanned)){
- js[["variables"]] <- paste(
- ifelse(is.null(js[["variables"]]), "", paste(js[["variables"]], "\n", sep="")),
- var.scanned,
- sep="")
+ if(isTRUE(edit)){
+ rk.edit.files(plugin.xml, title=plugin.fname.xml, prompt=FALSE)
} else {}
} else {}
- if("saveobj" %in% scan){
- saveobj.scanned <- rk.JS.saveobj(XML.plugin)
- if(!is.null(saveobj.scanned)){
- js[["printout"]] <- paste(js[["printout"]], saveobj.scanned, sep="\n")
+
+ ## create plugin.js
+ if("js" %in% create){
+ if(isTRUE(checkCreateFiles(plugin.js, ow=overwrite))){
+ cat(JS.code, file=plugin.js)
} else {}
+ if(isTRUE(edit)){
+ rk.edit.files(plugin.js, title=plugin.fname.js, prompt=FALSE)
+ } else {}
} else {}
- JS.code <- rk.JS.doc(
- require=js[["require"]],
- variables=js[["variables"]],
- results.header=js[["results.header"]],
- preprocess=js[["preprocess"]],
- calculate=js[["calculate"]],
- printout=js[["printout"]],
- indent.by=indent.by)
- cat(JS.code, file=plugin.js)
- } else {}
- if(isTRUE(edit)){
- rk.edit.files(plugin.js, title=plugin.fname.js, prompt=FALSE)
- } else {}
- } else {}
- ## create plugin.rkh
- if("rkh" %in% create){
- if(isTRUE(checkCreateFiles(plugin.rkh))){
- # summary=NULL, usage=NULL, sections=NULL, settings="scan", related=NULL, technical=NULL
- got.rkh.options <- names(rkh)
- # if settings were defined manually, this overwrites the scan
- if(!"settings" %in% got.rkh.options){
- if("settings" %in% scan){
- rkh[["settings"]] <- rk.rkh.settings(rk.rkh.scan(XML.plugin))
- } else {
- rkh[["settings"]] <- eval(formals(rk.rkh.doc)[["settings"]])
- }
- } else {}
- for (this.opt in c("summary", "usage", "sections", "related", "technical")){
- if(!this.opt %in% got.rkh.options) {
- rkh[[this.opt]] <- eval(formals(rk.rkh.doc)[[this.opt]])
+ ## create plugin.rkh
+ if("rkh" %in% create){
+ if(isTRUE(checkCreateFiles(plugin.rkh, ow=overwrite))){
+ cat(pasteXMLTree(rkh.doc, shine=1, indent.by=indent.by), file=plugin.rkh)
} else {}
- }
- rkh.doc <- rk.rkh.doc(
- summary=rkh[["summary"]],
- usage=rkh[["usage"]],
- sections=rkh[["sections"]],
- settings=rkh[["settings"]],
- related=rkh[["related"]],
- technical=rkh[["technical"]],
- title=rk.rkh.title(name.orig))
- cat(pasteXMLTree(rkh.doc, shine=1, indent.by=indent.by), file=plugin.rkh)
- } else {}
- if(isTRUE(edit)){
- rk.edit.files(plugin.rkh, title=plugin.fname.rkh, prompt=FALSE)
- } else {}
- } else {}
+ if(isTRUE(edit)){
+ rk.edit.files(plugin.rkh, title=plugin.fname.rkh, prompt=FALSE)
+ } else {}
+ } else {}
+ }
+ })
## create plugin.pluginmap
if("pmap" %in% create){
- if(isTRUE(checkCreateFiles(plugin.pluginmap))){
- got.pm.options <- names(pluginmap)
- for (this.opt in c("hierarchy", "require")){
- if(!this.opt %in% got.pm.options) {
- pluginmap[[this.opt]] <- eval(formals(rk.XML.pluginmap)[[this.opt]])
- } else {}
- }
+ if(isTRUE(checkCreateFiles(plugin.pluginmap, ow=overwrite))){
+ if(!"require" %in% got.pm.options) {
+ pluginmap[["require"]] <- eval(formals(rk.XML.pluginmap)[["require"]])
+ } else {}
if(!"name" %in% got.pm.options){
pluginmap[["name"]] <- name.orig
} else {}
+ # get components and hierarchy info from the components list
+ all.components <- sapply(components, function(this.comp){
+ paste("plugins/", clean.name(this.comp at name), ".xml", sep="")
+ })
+ all.hierarchies <- lapply(components, function(this.comp){
+ this.comp at hierarchy
+ })
XML.pluginmap <- rk.XML.pluginmap(
name=pluginmap[["name"]],
about=about,
- components=paste("plugins/", name, ".xml", sep=""),
- hierarchy=pluginmap[["hierarchy"]],
+ components=all.components,
+ hierarchy=all.hierarchies,
require=pluginmap[["require"]],
hints=TRUE)
cat(pasteXMLTree(XML.pluginmap, shine=2, indent.by=indent.by), file=plugin.pluginmap)
@@ -334,14 +293,14 @@
} else {}
## create testsuite.R
- if(isTRUE(tests) & isTRUE(checkCreateFiles(testsuite.file))){
+ if(isTRUE(tests) & isTRUE(checkCreateFiles(testsuite.file, ow=overwrite))){
testsuite.doc <- rk.testsuite.doc(name=name)
cat(testsuite.doc, file=testsuite.file)
} else {}
## create DESCRIPTION file
if("desc" %in% create){
- if(isTRUE(checkCreateFiles(description.file))){
+ if(isTRUE(checkCreateFiles(description.file, ow=overwrite))){
authors <- XML2person(about.node, eval=TRUE)
all.authors <- format(get.by.role(authors, role="aut"),
include=c("given", "family", "email"), braces=list(email=c("<", ">")))
Modified: trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R 2011-10-20 14:43:15 UTC (rev 3978)
@@ -3,8 +3,8 @@
#' \tabular{ll}{
#' Package: \tab rkwarddev\cr
#' Type: \tab Package\cr
-#' Version: \tab 0.04-0\cr
-#' Date: \tab 2011-10-19\cr
+#' Version: \tab 0.04-1\cr
+#' Date: \tab 2011-10-20\cr
#' Depends: \tab R (>= 2.9.0),XiMpLe,rkward (>= 0.5.7)\cr
#' Enhances: \tab rkward\cr
#' Encoding: \tab UTF-8\cr
Modified: trunk/rkward/packages/rkwarddev/inst/CITATION
===================================================================
--- trunk/rkward/packages/rkwarddev/inst/CITATION 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/inst/CITATION 2011-10-20 14:43:15 UTC (rev 3978)
@@ -2,12 +2,12 @@
title="rkwarddev: A collection of tools for RKWard plugin development",
author="Meik Michalke",
year="2011",
- note="(Version 0.04-0)",
+ note="(Version 0.04-1)",
url="http://rkward.sourceforge.net",
textVersion =
paste("Michalke, M. (2011). ",
- "rkwarddev: A collection of tools for RKWard plugin development (Version 0.04-0). ",
+ "rkwarddev: A collection of tools for RKWard plugin development (Version 0.04-1). ",
"Available from http://rkward.sourceforge.net",
sep=""),
Modified: trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.pdf
===================================================================
(Binary files differ)
Modified: trunk/rkward/packages/rkwarddev/man/rk.XML.plugin.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rk.XML.plugin.Rd 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/man/rk.XML.plugin.Rd 2011-10-20 14:43:15 UTC (rev 3978)
@@ -4,7 +4,8 @@
\usage{
rk.XML.plugin(name, dialog = NULL, wizard = NULL, logic =
NULL, snippets = NULL, provides = NULL, help = TRUE,
- pluginmap = NULL, label = NULL, clean.name = TRUE)
+ pluginmap = NULL, label = NULL, clean.name = TRUE, about
+ = NULL)
}
\arguments{
\item{name}{Character string, the name of the plugin.
@@ -55,6 +56,14 @@
\item{clean.name}{Logical, if \code{TRUE}, all
non-alphanumeric characters except the underscore
(\code{"_"}) will be removed from \code{name}.}
+
+ \item{about}{An object of class \code{XiMpLe.node} with
+ descriptive information on the plugin, its authors and
+ dependencies, 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}.}
}
\value{
An object of class \code{XiMpLe.doc}.
Added: trunk/rkward/packages/rkwarddev/man/rk.plugin.component.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rk.plugin.component.Rd (rev 0)
+++ trunk/rkward/packages/rkwarddev/man/rk.plugin.component.Rd 2011-10-20 14:43:15 UTC (rev 3978)
@@ -0,0 +1,134 @@
+\name{rk.plugin.component}
+\alias{rk.plugin.component}
+\title{Generate RKWard plugin components}
+\usage{
+ rk.plugin.component(name, about = NULL, xml = list(), js
+ = list(), rkh = list(), provides = c("logic", "dialog"),
+ scan = c("var", "saveobj", "settings"), hierarchy =
+ "test", pluginmap = NULL, create = c("xml", "js", "rkh"),
+ indent.by = "\t")
+}
+\arguments{
+ \item{name}{Character sting, name of this plugin
+ component.}
+
+ \item{about}{An object of class \code{XiMpLe.node} with
+ descriptive information on the plugin, its authors and
+ dependencies, 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}.}
+
+ \item{xml}{A named list of options to be forwarded to
+ \code{\link[rkwarddev:rk.XML.plugin]{rk.XML.plugin}}, to
+ generate the GUI XML file. Not all options are supported
+ because some don't make sense in this context. Valid
+ options are: \code{"dialog"}, \code{"wizard"},
+ \code{"logic"} and \code{"snippets"}. If not set, their
+ default values are used. See
+ \code{\link[rkwarddev:rk.XML.plugin]{rk.XML.plugin}} for
+ details.}
+
+ \item{js}{A named list of options to be forwarded to
+ \code{\link[rkwarddev:rk.JS.doc]{rk.JS.doc}}, to generate
+ the JavaScript file. Not all options are supported
+ because some don't make sense in this context. Valid
+ options are: \code{"require"}, \code{"results.header"},
+ \code{"variables"}, \code{"preprocess"},
+ \code{"calculate"} and \code{"printout"}. If not set,
+ their default values are used. See
+ \code{\link[rkwarddev:rk.JS.doc]{rk.JS.doc}} for
+ details.}
+
+ \item{rkh}{A named list of options to be forwarded to
+ \code{\link[rkwarddev:rk.rkh.doc]{rk.rkh.doc}}, to
+ generate the help file. Not all options are supported
+ because some don't make sense in this context. Valid
+ options are: \code{"summary"}, \code{"usage"},
+ \code{"sections"}, \code{"settings"}, \code{"related"}
+ and \code{"technical"}. If not set, their default values
+ are used. See
+ \code{\link[rkwarddev:rk.rkh.doc]{rk.rkh.doc}} for
+ details.}
+
+ \item{provides}{Character vector with possible entries of
+ \code{"logic"}, \code{"dialog"} or \code{"wizard"},
+ defining what sections the GUI XML file 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.}
+
+ \item{scan}{A character vector to trigger various
+ automatic scans of the generated GUI XML file. Valid
+ enties are: \describe{ \item{\code{"var"}}{Calls
+ \code{\link{rk.JS.scan}} to define all needed variables
+ in the \code{calculate()} function of the JavaScript
+ file. These variables will be added to variables defined
+ by the \code{js} option, if any (see below).}
+ \item{\code{"saveobj"}}{Calls \code{\link{rk.JS.saveobj}}
+ to generate code to save R results in the
+ \code{printout()} function of the JavaScript file. This
+ code will be added to the code defined by the \code{js}
+ option, if any (see below).}
+ \item{\code{"settings"}}{Calls \code{\link{rk.rkh.scan}}
+ to generate \code{<setting>} sections for each relevant
+ GUI element in the \code{<settings>} section of the help
+ file. This option will be overruled if you provide that
+ section manually by the \code{rkh} option (see below).}
+ }}
+
+ \item{hierarchy}{A character vector with instructions
+ where to place this component in the menu hierarchy, one
+ list or string. Valid single values are \code{"file"},
+ \code{"edit"}, \code{"view"}, \code{"workspace"},
+ \code{"run"}, \code{"data"}, \code{"analysis"},
+ \code{"plots"}, \code{"distributions"}, \code{"windows"},
+ \code{"settings"} and \code{"help"}, anything else will
+ place it in a "test" menu. If \code{hierarchy} is a list,
+ each entry represents the label of a menu level.}
+
+ \item{pluginmap}{Character string, relative path to the
+ pluginmap file, which will then be included in the head
+ of the GUI XML document.}
+
+ \item{create}{A character vector with one or more of
+ these possible entries: \describe{
+ \item{\code{"xml"}}{Create the plugin \code{.xml} XML
+ file skeleton.} \item{\code{"js"}}{Create the plugin
+ \code{.js} JavaScript file skeleton.}
+ \item{\code{"rkh"}}{Create the plugin \code{.rkh} help
+ file skeleton.} }}
+
+ \item{indent.by}{A character string defining the
+ indentation string to use.}
+}
+\value{
+ An object of class \code{rk.plug.comp}.
+}
+\description{
+ Generate RKWard plugin components
+}
+\examples{
+\dontrun{
+test.dropdown <- rk.XML.dropdown("mydrop",
+opts=list("First Option"=c(val="val1"),
+"Second Option"=c(val="val2", chk=TRUE)))
+test.checkboxes <- rk.XML.row(rk.XML.col(
+list(test.dropdown,
+rk.XML.cbox(label="foo", val="foo1", chk=TRUE),
+rk.XML.cbox(label="bar", val="bar2"))
+))
+test.vars <- rk.XML.vars("select some vars", "vars go here")
+test.tabbook <- rk.XML.dialog(rk.XML.tabbook("My Tabbook", tab.labels=c("First Tab",
+"Second Tab"), children=list(test.checkboxes, test.vars)))
+
+rk.plugin.component("Square the Circle",
+xml=list(dialog=test.tabbook))
+}
+}
+\seealso{
+ \href{help:rkwardplugins}{Introduction to Writing Plugins
+ for RKWard}
+}
+
Modified: trunk/rkward/packages/rkwarddev/man/rk.plugin.skeleton.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rk.plugin.skeleton.Rd 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/man/rk.plugin.skeleton.Rd 2011-10-20 14:43:15 UTC (rev 3978)
@@ -7,8 +7,8 @@
"saveobj", "settings"), xml = list(), js = list(),
pluginmap = list(), rkh = list(), overwrite = FALSE,
tests = TRUE, lazyLoad = TRUE, create = c("pmap", "xml",
- "js", "rkh", "desc"), edit = FALSE, load = FALSE, show =
- FALSE, indent.by = "\t")
+ "js", "rkh", "desc"), components = list(), edit = FALSE,
+ load = FALSE, show = FALSE, indent.by = "\t")
}
\arguments{
\item{name}{Character sting, name of the plugin package.}
@@ -128,7 +128,8 @@
\item{show}{Logical, if \code{TRUE} and \code{"pmap"} in
\code{create}, RKWard will automatically call the created
plugin after it was loaded (i.e., this implies and also
- sets \code{load=TRUE}).}
+ sets \code{load=TRUE}). This will only work on the main
+ component, though.}
\item{indent.by}{A character string defining the
indentation string to use.}
@@ -138,7 +139,12 @@
directory.
}
\description{
- Generate skeletons for RKWard plugins
+ With this function you can write everything from a basic
+ skeleton structure to a complete functional plugin,
+ including several components/dialogs. You should always
+ define one main component (by \code{xml}, \code{js},
+ \code{rkh} etc.) before you provide additional features
+ by \code{components}.
}
\examples{
\dontrun{
Modified: trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd 2011-10-20 13:10:13 UTC (rev 3977)
+++ trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd 2011-10-20 14:43:15 UTC (rev 3978)
@@ -8,8 +8,8 @@
}
\details{
\tabular{ll}{ Package: \tab rkwarddev\cr Type: \tab
- Package\cr Version: \tab 0.04-0\cr Date: \tab
- 2011-10-19\cr Depends: \tab R (>= 2.9.0),XiMpLe,rkward
+ Package\cr Version: \tab 0.04-1\cr Date: \tab
+ 2011-10-20\cr Depends: \tab R (>= 2.9.0),XiMpLe,rkward
(>= 0.5.7)\cr Enhances: \tab rkward\cr Encoding: \tab
UTF-8\cr License: \tab GPL (>= 3)\cr LazyLoad: \tab
yes\cr URL: \tab http://rkward.sourceforge.net\cr }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the rkward-tracker
mailing list