[rkward-cvs] SF.net SVN: rkward-code:[4935] trunk/rkward/packages/rkwarddev

m-eik at users.sf.net m-eik at users.sf.net
Sat Oct 18 22:23:40 UTC 2014


Revision: 4935
          http://sourceforge.net/p/rkward/code/4935
Author:   m-eik
Date:     2014-10-18 22:23:39 +0000 (Sat, 18 Oct 2014)
Log Message:
-----------
rkwarddev: getting closer to a solution for optionsets. but suffixing the column IDs with an index inside the for loop turns out to be a real tough one...

Modified Paths:
--------------
    trunk/rkward/packages/rkwarddev/ChangeLog
    trunk/rkward/packages/rkwarddev/DESCRIPTION
    trunk/rkward/packages/rkwarddev/NAMESPACE
    trunk/rkward/packages/rkwarddev/R/id.R
    trunk/rkward/packages/rkwarddev/R/rk-internal.R
    trunk/rkward/packages/rkwarddev/R/rk.XML.radio.R
    trunk/rkward/packages/rkwarddev/R/rk.XML.select.R
    trunk/rkward/packages/rkwarddev/R/rk.XML.valueselector.R
    trunk/rkward/packages/rkwarddev/R/rk.paste.JS.R
    trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R
    trunk/rkward/packages/rkwarddev/R/show-methods.R
    trunk/rkward/packages/rkwarddev/inst/NEWS.Rd
    trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.pdf
    trunk/rkward/packages/rkwarddev/man/rk.XML.valueselector.Rd
    trunk/rkward/packages/rkwarddev/man/rk.paste.JS.Rd
    trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd
    trunk/rkward/packages/rkwarddev/man/show-methods.Rd

Added Paths:
-----------
    trunk/rkward/packages/rkwarddev/R/rk.JS.optionset.R
    trunk/rkward/packages/rkwarddev/R/rk.JS.oset-class.R
    trunk/rkward/packages/rkwarddev/man/rk.JS.optionset.Rd

Modified: trunk/rkward/packages/rkwarddev/ChangeLog
===================================================================
--- trunk/rkward/packages/rkwarddev/ChangeLog	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/ChangeLog	2014-10-18 22:23:39 UTC (rev 4935)
@@ -19,6 +19,7 @@
   - all functions scanned by rk.rkh.scan() for setting nodes in .rkh files have gained two additional arguments,
     "help" and "component", to register the text to be used via rk.set.rkh.prompter()
   - new function rk.XML.option() to allow setting and accessing IDs for single options as well
+  - new function rk.JS.optionset() and object class "rk.JS.oset" to generate for loops over <optionset> columns
 changed:
   - updated the plugin skeleton example script; e.g., it now uses the new .rkh file generating features
   - rk.XML.radio() and rk.XML.dropdown() now also accept objects made with rk.XML.option() in their respective

Modified: trunk/rkward/packages/rkwarddev/DESCRIPTION
===================================================================
--- trunk/rkward/packages/rkwarddev/DESCRIPTION	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/DESCRIPTION	2014-10-18 22:23:39 UTC (rev 4935)
@@ -15,7 +15,7 @@
 Authors at R: c(person(given="Meik", family="Michalke",
     email="meik.michalke at hhu.de", role=c("aut", "cre")))
 Version: 0.06-5
-Date: 2014-10-18
+Date: 2014-10-19
 Collate:
     'echo.R'
     'i18n.R'
@@ -31,9 +31,11 @@
     'rk.JS.doc.R'
     'rk.JS.opt-class.R'
     'rk.JS.options.R'
+    'rk.JS.optionset.R'
+    'rk.JS.var-class.R'
+    'rk.JS.oset-class.R'
     'rk.JS.saveobj.R'
     'rk.JS.scan.R'
-    'rk.JS.var-class.R'
     'rk.JS.vars.R'
     'rk.XML.about.R'
     'rk.XML.attribute.R'

Modified: trunk/rkward/packages/rkwarddev/NAMESPACE
===================================================================
--- trunk/rkward/packages/rkwarddev/NAMESPACE	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/NAMESPACE	2014-10-18 22:23:39 UTC (rev 4935)
@@ -9,6 +9,7 @@
 export(rk.JS.array)
 export(rk.JS.doc)
 export(rk.JS.options)
+export(rk.JS.optionset)
 export(rk.JS.saveobj)
 export(rk.JS.scan)
 export(rk.JS.vars)
@@ -101,6 +102,7 @@
 exportClasses(rk.JS.arr)
 exportClasses(rk.JS.ite)
 exportClasses(rk.JS.opt)
+exportClasses(rk.JS.oset)
 exportClasses(rk.JS.var)
 exportClasses(rk.plot.opts)
 exportClasses(rk.plug.comp)

Modified: trunk/rkward/packages/rkwarddev/R/id.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/id.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/id.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -56,10 +56,8 @@
           # optionsets are more difficult to identify automatically
           if(isTRUE(js)){
             node.id <- camelCode(get.IDs(check.optionset.tags(this.part), relevant.tags="optioncolumn")[,"abbrev"])
-#            node.id <- check.ID(this.part, search.environment=TRUE, env.get="JS")
           } else {
             node.id <- get.IDs(check.optionset.tags(this.part), relevant.tags="optioncolumn")[,"id"]
-#            node.id <- check.ID(this.part, search.environment=TRUE, env.get="XML")
           }
         } else {
           node.id <- XMLAttrs(this.part)[["id"]]
@@ -91,6 +89,13 @@
         } else {
           text.part <- this.part
         }
+        # check for temoprary object to add inices for a for loop, see internal function paste.JS.optionsset()
+        addLoopIndex <- get.rk.env(name="IDLoopIndex", value=NULL)
+        if(!is.null(addLoopIndex)){
+          if(text.part %in% addLoopIndex[["columnIDs"]]){
+            text.part <- paste0(text.part, "[", addLoopIndex[["loopvar"]], "]")
+          } else {}
+        } else {}
         return(text.part)
       }
     })

Modified: trunk/rkward/packages/rkwarddev/R/rk-internal.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk-internal.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/rk-internal.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -188,33 +188,21 @@
   ids <- t(sapply(cleaned.tags, function(this.tag){
         if(is.XiMpLe.node(this.tag)){
           this.tag.name <- XMLName(this.tag)
-          this.tag.id.abbrev <- this.tag.id <- XMLAttrs(this.tag)["id"]
-          # take care of one special case: optionsets
-          # they need the set ID to access the value from the dialog,
-          # but to be able to use only the optioncolumn in rkwaddev scripts
-          # as reference, the JavaScript variable must be generated from the
-          # column ID alone.
-          if(identical(this.tag.name, "optioncolumn")){
-            this.tag.setid <- XMLAttrs(this.tag)[["setid"]]
-            if(!is.null(this.tag.setid)){
-              this.tag.id <- paste(this.tag.setid, this.tag.id, sep=".")
-            } else {}
-            # for safety, prefix the column ID with a constant
-            this.tag.id.abbrev <- paste0("ocol_", this.tag.id.abbrev)
-          } else {}
+          this.tag.id.abbrev <- this.tag.id <- check.ID(this.tag)
         } else {
           this.tag.name <- XiMpLe:::XML.tagName(this.tag)
           this.tag.id.abbrev <- this.tag.id <- XiMpLe:::parseXMLAttr(this.tag)[["id"]]
-          # see comment above for the next part
-          if(identical(this.tag.name, "optioncolumn")){
-            this.tag.setid <- XiMpLe:::parseXMLAttr(this.tag)[["setid"]]
-            if(!is.null(this.tag.setid)){
-              this.tag.id <- paste(this.tag.setid, this.tag.id, sep=".")
-            } else {}
-            # for safety, prefix the column ID with a constant
-            this.tag.id.abbrev <- paste0("ocol_", this.tag.id.abbrev)
-          } else {}
         }
+        # take care of one special case: optionsets
+        # they need the set ID to access the value from the dialog,
+        # but to be able to use only the optioncolumn in rkwaddev scripts
+        # as reference, the JavaScript variable must be generated from the
+        # column ID alone.
+        if(identical(this.tag.name, "optioncolumn")){
+          this.tag.id <- check.ID(this.tag.id, search.environment=TRUE)
+          # for safety, prefix the column ID with a constant
+          this.tag.id.abbrev <- paste0("ocol_", this.tag.id.abbrev)
+        } else {}
 
         if(isTRUE(add.abbrev)){
           this.tag.id.abbrev <- paste0(ID.prefix(this.tag.name), this.tag.id.abbrev)
@@ -255,27 +243,18 @@
   # first get a list of all optionsets
   optionset.nodes <- child.list(XMLScan(XML.obj, "optionset"))
   # are there any?
-  if(is.null(optionset.nodes)){
-    result <- get.single.tags(XML.obj=XML.obj, drop=drop)
-  } else {
-    # now go through all sets and combine setID with the IDs of optioncolumns
-    optioncolumnNewIDs <- unlist(sapply(optionset.nodes, function(thisNode){
-        thisCols <- child.list(XMLScan(thisNode, "optioncolumn"))
-        thisSetID <- XMLAttrs(thisNode)[["id"]]
-        thisNewCols <- unlist(sapply(thisCols, function(thisCol){
-            XMLAttrs(thisCol)[["setid"]] <- thisSetID
-            pastedTag <- get.single.tags(XML.obj=thisCol, drop=drop)
-            return(pastedTag)
-          }, USE.NAMES=FALSE))
-        return(thisNewCols)
-      }, USE.NAMES=FALSE))
-    # we don't need the set nodes any longer
-    XMLScan(XML.obj, "optionset") <- NULL
-    result <- c(optioncolumnNewIDs, get.single.tags(XML.obj=XML.obj, drop=drop))
-  }
+  if(!is.null(optionset.nodes)){
+    for (thisNode in optionset.nodes){
+      optioncolumn.nodes <- child.list(XMLScan(thisNode, "optioncolumn"))
+      # register column and set IDs internally
+      rk.register.options(optioncolumn.nodes, parent.node=thisNode)
+    }
+  } else {}
+  result <- get.single.tags(XML.obj=XML.obj, drop=drop)
   return(result)
 } ## end function check.optionset.tags()
 
+
 ## function camelCode()
 # changes the first letter of each string
 # (except for the first one) to upper case
@@ -366,7 +345,7 @@
 # in XML will become
 #   var my.id = getValue("my.id");
 get.JS.vars <- function(JS.var, XML.var=NULL, tag.name=NULL, JS.prefix="", names.only=FALSE, modifiers=NULL, default=FALSE, join="",
-  getter="getValue", guess.getter=FALSE, check.modifiers=TRUE){
+  getter="getValue", guess.getter=FALSE, check.modifiers=TRUE, search.environment=FALSE){
   # check for XiMpLe nodes
   JS.var <- check.ID(JS.var)
   have.XiMpLe.var <- FALSE
@@ -401,7 +380,6 @@
       }
     } else {}
 
-
     # check for getter guessing
     if(isTRUE(guess.getter)){
       if(tag.name %in% names(JS.getters.default)){
@@ -440,9 +418,9 @@
           "Using the default getValue() on this node might cause problems!"), call.=FALSE)
       } else {}
     }
-    XML.var <- check.ID(XML.var)
+    XML.var <- check.ID(XML.var, search.environment=search.environment)
   } else {
-    XML.var <- check.ID(JS.var)
+    XML.var <- check.ID(JS.var, search.environment=search.environment)
   }
 
   if(is.null(JS.prefix)){
@@ -642,6 +620,10 @@
     } else {}
   } else if(is.character(node)){
     node.ID <- node
+    if(isTRUE(search.environment)){
+      optionIDs <- get.optionIDs()[[node.ID]]
+      node.ID <- ifelse(is.null(optionIDs), node.ID, optionIDs[[env.get]])
+    } else {}
   } else {
     stop(simpleError("Can't find an ID!"))
   }
@@ -773,6 +755,7 @@
   radio=c("option"),
   select=c("option"),
   settings=c("setting", "caption", "!--"),
+  valueselector=c("option"),
   wizard=c("browser", "checkbox", "column", "copy",
     "dropdown", "embed", "formula", "frame", "include", "input", "insert", "matrix",
     "optionset", "page", "preview", "radio", "row", "saveobject", "spinbox", "stretch",
@@ -1160,6 +1143,49 @@
 } ## end function paste.JS.var()
 
 
+## function paste.JS.optionsset()
+paste.JS.optionsset <- function(object, level=2, indent.by="\t"){
+  stopifnot(inherits(object, "rk.JS.oset"))
+  # check indentation
+  main.indent <- indent(level, by=indent.by)
+  scnd.indent <- indent(level+1, by=indent.by)
+
+  vars <- slot(object, "vars")
+  loopvar <- slot(object, "loopvar")
+  columns <- slot(object, "columns")
+  body <- slot(object, "body")
+
+  if(length(slot(vars, "vars")) > 0 | length(slot(vars, "JS.var")) > 0 ){
+    paste.vars <- paste.JS.var(vars, level=level, indent.by=indent.by)
+  } else {
+    paste.vars <- c()
+  }
+
+  ## the for loop body
+#   for (var i = 0; i < col_a.length; ++i) {
+#         echo ("coolfun (", col_a[i] + ", " + col_b[i] + "," + col_c[i] + ")\n");
+#   }
+  for.head <- paste0(main.indent, "for (var ", loopvar, " = 0; ", loopvar, " < ", id(columns[[1]]), ".length; ++", loopvar, "){")
+
+  # place a temporary object in the internal environment to cause id() to add an index to the column IDs
+  set.rk.env(
+    name="IDLoopIndex",
+    value=list(
+      columnIDs=sapply(columns, id),
+      loopvar=loopvar
+    )
+  )
+  paste.body <- rk.paste.JS(body, level=level, indent.by=scnd.indent)
+  # remove teporary object
+  set.rk.env(name="IDLoopIndex", value=NULL)
+
+  for.foot <- paste0(main.indent, "}")
+  
+  results <- paste(c(paste.vars, for.head, paste.body, for.foot), collapse="\n")
+  return(results)
+} ## end function paste.JS.optionsset()
+
+
 ## function dependenciesCompatWrapper()
 # with RKWard 0.6.1, the dependencies will no longer be a part of <about>
 # this wrapper takes both, "about" and "dependencies" arguments,
@@ -1294,7 +1320,7 @@
       if(!is.null(opt.id)){
         # save ID with parents
         optionIDs <- get.optionIDs()
-        thisID <- c(XML=id(options[[this.num]], js=FALSE), JS=id(options[[this.num]]))
+        thisID <- c(XML=opt.id, JS=id(options[[this.num]]))
         parentID <- c(XML=id(parent.node, js=FALSE), JS=id(parent.node))
         optionIDs[[opt.id]] <- list(
           XML=paste(parentID[["XML"]], thisID[["XML"]], sep="."),

Added: trunk/rkward/packages/rkwarddev/R/rk.JS.optionset.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.JS.optionset.R	                        (rev 0)
+++ trunk/rkward/packages/rkwarddev/R/rk.JS.optionset.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -0,0 +1,72 @@
+# Copyright 2010-2014 Meik Michalke <meik.michalke at 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/>.
+
+#' Evaluate optionset objects in plugin JavaScript
+#' 
+#' This function scans an object generated by \code{\link[rkwarddev:rk.XML.optionset]{rk.XML.optionset}},
+#' extract IDs of all optioncolumn objects and nest the JavaScript code you define via \code{...} inside
+#' a for loop that iterates through all columns. Inside \code{...}, you can use the column objects of
+#' \code{\link[rkwarddev:rk.XML.optioncolumn]{rk.XML.optioncolumn}} to refer to the respective column,
+#' \code{rk.JS.optionset} will use appropriate variables.
+#' 
+#' @param optionset A XiMpLe.node object, the full \code{<optionset>} node.
+#' @param ... The JavaScript code, optionally including the optioncolumn objects. This will become
+#'    the body of the for loop.
+#' @param loopvar Character, name of the index variable used in the for loop.
+#' @param vars Logical, if \code{TRUE} all optioncolumn varaibles will be defined first. This is not
+#'    needed if \code{\link[rkwarddev:rk.JS.scan]{rk.JS.scan}} was already called.
+#' @param guess.getter Logical, if \code{TRUE} try to get a good default getter function for JavaScript
+#'    variable values. Only relevant if \code{vars=TRUE}.
+#' @export
+#' @seealso
+#'    \code{\link[rkwarddev:rk.XML.optionset]{rk.XML.optionset}}, 
+#'    \code{\link[rkwarddev:rk.XML.optioncolumn]{rk.XML.optioncolumn}}
+
+rk.JS.optionset <- function(optionset, ..., loopvar="i", vars=FALSE, guess.getter=TRUE){
+  optioncolumn.nodes <- child.list(XMLScan(optionset, "optioncolumn"))
+  loopbody <- list(...)
+
+  if(isTRUE(vars)){
+    # define all optioncolumn variables
+    JS.vars <- new("rk.JS.var",
+      vars=sapply(optioncolumn.nodes, function(this.var){get.JS.vars(
+          JS.var=this.var,
+          XML.var=this.var,
+          JS.prefix="ocol",
+          modifiers=NULL,
+          default=FALSE,
+          join="",
+          check.modifiers=FALSE,
+          getter="getValue",
+          guess.getter=guess.getter,
+          search.environment=TRUE)
+      })
+    )
+  } else {
+    JS.vars <- new("rk.JS.var")
+  }
+  
+  # the for loop
+  JS.osfor <- new("rk.JS.oset",
+    vars=JS.vars,
+    loopvar=loopvar,
+    columns=optioncolumn.nodes,
+    body=loopbody
+  )
+
+  return(JS.osfor)
+}
\ No newline at end of file

Added: trunk/rkward/packages/rkwarddev/R/rk.JS.oset-class.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.JS.oset-class.R	                        (rev 0)
+++ trunk/rkward/packages/rkwarddev/R/rk.JS.oset-class.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -0,0 +1,50 @@
+# Copyright 2014 Meik Michalke <meik.michalke at 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/>.
+
+
+#' @include rk.JS.var-class.R
+#' @export
+
+# this simple class is for JavaScript generation,
+# produced by rk.JS.optionset()
+
+setClass("rk.JS.oset",
+  representation=representation(
+    vars="rk.JS.var",
+    loopvar="character",
+    columns="list",
+    body="list"
+  ),
+  prototype(
+    vars=new("rk.JS.var"),
+    loopvar="i",
+    columns=list(),
+    body=list()
+  )
+)
+
+setValidity("rk.JS.oset", function(object){
+    sapply(slot(object, "columns"), function(this.col){
+      if(!inherits(this.col, "XiMpLe.node")){
+        stop(simpleError("Slot 'columns' can only have a list of elements of class 'XiMpLe.node'!"))
+      } else {}
+      if(!identical(XMLName(this.col), "optioncolumn")){
+        stop(simpleError("Slot 'columns' can only have a list of <optioncolumn> nodes!"))
+      } else {}
+    })
+  return(TRUE)
+})

Modified: trunk/rkward/packages/rkwarddev/R/rk.XML.radio.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.XML.radio.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/rk.XML.radio.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -55,6 +55,9 @@
   # convert list elements into a list of XiMpLe nodes (if they aren't already)
   rd.options <- rk.check.options(options, parent="radio")
 
+  # check the node names and allow only valid ones
+  valid.child("radio", children=rd.options)
+
   radio <- XMLNode("radio",
       attrs=rd.attr.list,
       .children=child.list(rd.options, empty=FALSE)

Modified: trunk/rkward/packages/rkwarddev/R/rk.XML.select.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.XML.select.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/rk.XML.select.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -51,6 +51,9 @@
   # convert list elements into a list of XiMpLe nodes (if they aren't already)
   sl.options <- rk.check.options(options, parent="select")
 
+  # check the node names and allow only valid ones
+  valid.child("select", children=sl.options)
+
   select <- XMLNode("select",
       attrs=slct.attr.list,
       .children=child.list(sl.options, empty=FALSE)

Modified: trunk/rkward/packages/rkwarddev/R/rk.XML.valueselector.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.XML.valueselector.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/rk.XML.valueselector.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -20,18 +20,23 @@
 #'
 #' @param label Character string, a text label for the value selection slot.
 #'    Must be set if \code{id.name="auto"}.
+#' @param options A named list with string values to choose from. The names of the list elements will become
+#'    labels of the options, \code{val} defines the value to submit if the value is selected, and
+#'    \code{chk=TRUE} should be set in the one option which is checked by default. Objects generated with
+#'    \code{\link[rkwarddev:rk.XML.option]{rk.XML.option}} are accepted as well.
 #' @param id.name Character vector, unique ID for this element.
 #' @return An object of class \code{XiMpLe.node}.
 #' @export
 #' @seealso
 #'    \code{\link[rkwarddev:rk.XML.valueslot]{rk.XML.valueslot}},
 #'    \code{\link[rkwarddev:rk.XML.values]{rk.XML.values}},
+#'    \code{\link[rkwarddev:rk.XML.option]{rk.XML.option}},
 #'    and the \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
 #' @examples
 #' test.valueselector <- rk.XML.valueselector("Select some values")
 #' cat(pasteXML(test.valueselector))
 
-rk.XML.valueselector <- function(label=NULL, id.name="auto"){
+rk.XML.valueselector <- function(label=NULL, options=list(label=c(val=NULL, chk=FALSE)), id.name="auto"){
   if(identical(id.name, "auto")){
     ## if this ID generation get's changed, change it in rk.XML.vars(), too!
     attr.list <- list(id=auto.ids(label, prefix=ID.prefix("valueselector", length=3)))
@@ -47,7 +52,16 @@
     } else {}
   }
 
-  node <- XMLNode("valueselector", attrs=attr.list)
+  # convert list elements into a list of XiMpLe nodes (if they aren't already)
+  vs.options <- rk.check.options(options, parent="valueselector")
 
+  # check the node names and allow only valid ones
+  valid.child("valueselector", children=vs.options)
+
+  node <- XMLNode("valueselector",
+    attrs=attr.list,
+    .children=child.list(vs.options, empty=FALSE)
+  )
+
   return(node)
 }

Modified: trunk/rkward/packages/rkwarddev/R/rk.paste.JS.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rk.paste.JS.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/rk.paste.JS.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -20,7 +20,7 @@
 #'
 #' @note To get a list of the implemented modifiers in this package, call \code{rkwarddev:::all.valid.modifiers}.
 #'
-#' @param ... Objects of class \code{rk.JS.ite}, \code{rk.JS.arr}, \code{rk.JS.opt} or character.
+#' @param ... Objects of class \code{rk.JS.ite}, \code{rk.JS.arr}, \code{rk.JS.opt}, \code{rk.JS.oset} or character.
 #'    Another special case is XiMpLe nodes created by \code{rk.comment()}, which will be turned
 #'    into JavaScript comments (i.e., lines starting with "//").
 #' @param level Integer, which indentation level to use, minimum is 1.
@@ -46,10 +46,12 @@
 #' @include rk.JS.arr-class.R
 #' @include rk.JS.ite-class.R
 #' @include rk.JS.opt-class.R
+#' @include rk.JS.oset-class.R
 #' @include rk.JS.var-class.R
 #' @seealso
 #'    \code{\link[rkwarddev:rk.JS.array]{rk.JS.array}},
 #'    \code{\link[rkwarddev:rk.JS.options]{rk.JS.options}},
+#'    \code{\link[rkwarddev:rk.JS.optionset]{rk.JS.optionset}},
 #'    \code{\link[rkwarddev:rk.JS.vars]{rk.JS.vars}},
 #'    \code{\link[rkwarddev:ite]{ite}},
 #'    and the \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
@@ -73,6 +75,8 @@
       result <- paste.JS.array(this.object, level=level, indent.by=indent.by, funct=funct)
     } else if(inherits(this.object, "rk.JS.opt")){
       result <- paste.JS.options(this.object, level=level, indent.by=indent.by, array=array, funct=funct)
+    } else if(inherits(this.object, "rk.JS.oset")){
+      result <- paste.JS.optionsset(this.object, level=level, indent.by=indent.by)
     } else if(inherits(this.object, "rk.JS.var")){
       result <- paste.JS.var(this.object, level=level, indent.by=indent.by, JS.prefix=var.prefix,
         modifiers=modifiers, default=default, join=join, getter=getter)

Modified: trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/rkwarddev-package.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -4,7 +4,7 @@
 #' Package: \tab rkwarddev\cr
 #' Type: \tab Package\cr
 #' Version: \tab 0.06-5\cr
-#' Date: \tab 2014-10-18\cr
+#' Date: \tab 2014-10-19\cr
 #' Depends: \tab R (>= 2.9.0),methods,XiMpLe (>= 0.03-21),rkward (>= 0.5.7)\cr
 #' Enhances: \tab rkward\cr
 #' Encoding: \tab UTF-8\cr

Modified: trunk/rkward/packages/rkwarddev/R/show-methods.R
===================================================================
--- trunk/rkward/packages/rkwarddev/R/show-methods.R	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/R/show-methods.R	2014-10-18 22:23:39 UTC (rev 4935)
@@ -18,14 +18,14 @@
 
 #' Show methods for S4 objects of class \code{rk.JS.*}
 #'
-#' @title Show methods for objects of class rk.JS.S
 #' @param object An object of class \code{rk.JS.*}
-#' @aliases show,-methods show,rk.JS.ite-method show,rk.JS.arr-method show,rk.JS.opt-method show,rk.JS.var-method
+#' @aliases show,-methods show,rk.JS.ite-method show,rk.JS.arr-method show,rk.JS.opt-method show,rk.JS.oset-method show,rk.JS.var-method
 #' @keywords methods
 #' @import methods
 #' @include rk.JS.arr-class.R
 #' @include rk.JS.ite-class.R
 #' @include rk.JS.opt-class.R
+#' @include rk.JS.oset-class.R
 #' @include rk.JS.var-class.R
 #' @include echo.R
 #' @exportMethod show
@@ -48,6 +48,11 @@
 })
 
 #' @rdname show-methods
+setMethod("show", signature(object="rk.JS.oset"), function(object){
+  cat(rk.paste.JS(object))
+})
+
+#' @rdname show-methods
 setMethod("show", signature(object="rk.JS.var"), function(object){
   cat(rk.paste.JS(object))
 })

Modified: trunk/rkward/packages/rkwarddev/inst/NEWS.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/inst/NEWS.Rd	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/inst/NEWS.Rd	2014-10-18 22:23:39 UTC (rev 4935)
@@ -24,6 +24,7 @@
       \item all functions scanned by \code{rk.rkh.scan()} for setting nodes in .rkh files have gained two additional arguments,
         \code{"help"} and \code{"component"}, to register the text to be used via \code{rk.set.rkh.prompter()}
       \item new function \code{rk.XML.option()} to allow setting and accessing IDs for single options as well
+      \item new function \code{rk.JS.optionset()} and object class \code{"rk.JS.oset"} to generate for loops over <optionset> columns
     }
   }
   \subsection{changed}{

Modified: trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.pdf
===================================================================
(Binary files differ)

Added: trunk/rkward/packages/rkwarddev/man/rk.JS.optionset.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rk.JS.optionset.Rd	                        (rev 0)
+++ trunk/rkward/packages/rkwarddev/man/rk.JS.optionset.Rd	2014-10-18 22:23:39 UTC (rev 4935)
@@ -0,0 +1,38 @@
+% Generated by roxygen2 (4.0.2): do not edit by hand
+\name{rk.JS.optionset}
+\alias{rk.JS.optionset}
+\title{Evaluate optionset objects in plugin JavaScript}
+\usage{
+rk.JS.optionset(optionset, ..., loopvar = "i", vars = FALSE,
+  guess.getter = TRUE)
+}
+\arguments{
+\item{optionset}{A XiMpLe.node object, the full \code{<optionset>} node.}
+
+\item{...}{The JavaScript code,
+      optionally including the optioncolumn objects. This will become
+the body of the for loop.}
+
+\item{loopvar}{Character, name of the index variable used in the for loop.}
+
+\item{vars}{Logical,
+      if \code{TRUE} all optioncolumn varaibles will be defined first. This is not
+needed if \code{\link[rkwarddev:rk.JS.scan]{rk.JS.scan}} was already called.}
+
+\item{guess.getter}{Logical,
+      if \code{TRUE} try to get a good default getter function for JavaScript
+variable values. Only relevant if \code{vars=TRUE}.}
+}
+\description{
+This function scans an object generated by \code{\link[rkwarddev:rk.XML.optionset]{rk.XML.optionset}},
+extract IDs of all optioncolumn objects and nest the JavaScript code you define via \code{...} inside
+a for loop that iterates through all columns. Inside \code{...},
+      you can use the column objects of
+\code{\link[rkwarddev:rk.XML.optioncolumn]{rk.XML.optioncolumn}} to refer to the respective column,
+\code{rk.JS.optionset} will use appropriate variables.
+}
+\seealso{
+\code{\link[rkwarddev:rk.XML.optionset]{rk.XML.optionset}},
+   \code{\link[rkwarddev:rk.XML.optioncolumn]{rk.XML.optioncolumn}}
+}
+

Modified: trunk/rkward/packages/rkwarddev/man/rk.XML.valueselector.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rk.XML.valueselector.Rd	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/man/rk.XML.valueselector.Rd	2014-10-18 22:23:39 UTC (rev 4935)
@@ -3,12 +3,19 @@
 \alias{rk.XML.valueselector}
 \title{Create node "valueselector" for RKWard plugins}
 \usage{
-rk.XML.valueselector(label = NULL, id.name = "auto")
+rk.XML.valueselector(label = NULL, options = list(label = c(val = NULL, chk
+  = FALSE)), id.name = "auto")
 }
 \arguments{
 \item{label}{Character string, a text label for the value selection slot.
 Must be set if \code{id.name="auto"}.}
 
+\item{options}{A named list with string values to choose from. The names of the list elements will become
+labels of the options, \code{val} defines the value to submit if the value is selected,
+      and
+\code{chk=TRUE} should be set in the one option which is checked by default. Objects generated with
+\code{\link[rkwarddev:rk.XML.option]{rk.XML.option}} are accepted as well.}
+
 \item{id.name}{Character vector, unique ID for this element.}
 }
 \value{
@@ -24,6 +31,7 @@
 \seealso{
 \code{\link[rkwarddev:rk.XML.valueslot]{rk.XML.valueslot}},
    \code{\link[rkwarddev:rk.XML.values]{rk.XML.values}},
+   \code{\link[rkwarddev:rk.XML.option]{rk.XML.option}},
    and the \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}
 }
 

Modified: trunk/rkward/packages/rkwarddev/man/rk.paste.JS.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rk.paste.JS.Rd	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/man/rk.paste.JS.Rd	2014-10-18 22:23:39 UTC (rev 4935)
@@ -8,8 +8,8 @@
   join = NULL, getter = NULL, empty.e = FALSE)
 }
 \arguments{
-\item{...}{Objects of class \code{rk.JS.ite}, \code{rk.JS.arr},
-      \code{rk.JS.opt} or character.
+\item{...}{Objects of class \code{rk.JS.ite}, \code{rk.JS.arr}, \code{rk.JS.opt},
+      \code{rk.JS.oset} or character.
 Another special case is XiMpLe nodes created by \code{rk.comment()}, which will be turned
 into JavaScript comments (i.e., lines starting with "//").}
 
@@ -66,6 +66,7 @@
 \seealso{
 \code{\link[rkwarddev:rk.JS.array]{rk.JS.array}},
    \code{\link[rkwarddev:rk.JS.options]{rk.JS.options}},
+   \code{\link[rkwarddev:rk.JS.optionset]{rk.JS.optionset}},
    \code{\link[rkwarddev:rk.JS.vars]{rk.JS.vars}},
    \code{\link[rkwarddev:ite]{ite}},
    and the \href{help:rkwardplugins}{Introduction to Writing Plugins for RKWard}

Modified: trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/man/rkwarddev-package.Rd	2014-10-18 22:23:39 UTC (rev 4935)
@@ -11,7 +11,7 @@
 Package: \tab rkwarddev\cr
 Type: \tab Package\cr
 Version: \tab 0.06-5\cr
-Date: \tab 2014-10-18\cr
+Date: \tab 2014-10-19\cr
 Depends: \tab R (>= 2.9.0),methods,XiMpLe (>= 0.03-21),rkward (>= 0.5.7)\cr
 Enhances: \tab rkward\cr
 Encoding: \tab UTF-8\cr

Modified: trunk/rkward/packages/rkwarddev/man/show-methods.Rd
===================================================================
--- trunk/rkward/packages/rkwarddev/man/show-methods.Rd	2014-10-18 17:27:35 UTC (rev 4934)
+++ trunk/rkward/packages/rkwarddev/man/show-methods.Rd	2014-10-18 22:23:39 UTC (rev 4935)
@@ -7,8 +7,9 @@
 \alias{show,rk.JS.echo-method}
 \alias{show,rk.JS.ite-method}
 \alias{show,rk.JS.opt-method}
+\alias{show,rk.JS.oset-method}
 \alias{show,rk.JS.var-method}
-\title{Show methods for objects of class rk.JS.S}
+\title{Show methods for S4 objects of class \code{rk.JS.*}}
 \usage{
 show(object)
 
@@ -18,6 +19,8 @@
 
 \S4method{show}{rk.JS.opt}(object)
 
+\S4method{show}{rk.JS.oset}(object)
+
 \S4method{show}{rk.JS.var}(object)
 
 \S4method{show}{rk.JS.echo}(object)





More information about the rkward-tracker mailing list