[rkward] packages/rkwarddev: added for loops to the arsenal of js()

m.eik michalke meik.michalke at uni-duesseldorf.de
Tue Oct 27 15:28:32 UTC 2015


Git commit ebee828b9664556cf6bc6a0bf7ad8da492610f9e by m.eik michalke.
Committed on 27/10/2015 at 15:27.
Pushed by meikm into branch 'master'.

added for loops to the arsenal of js()

  - js() can now also translate for loops from R into a JavaScript equivalent. unfortunately, due
    to the differences in the syntax used in JavaScript, there's no way of doing this without two
    randomly named helper variables.

M  +6    -4    packages/rkwarddev/ChangeLog
M  +5    -4    packages/rkwarddev/DESCRIPTION
M  +9    -1    packages/rkwarddev/R/js.R
M  +31   -1    packages/rkwarddev/R/rk-internal.R
M  +1    -1    packages/rkwarddev/R/rkwarddev-package.R
M  +6    -4    packages/rkwarddev/inst/NEWS.Rd
M  +8    -1    packages/rkwarddev/man/js.Rd
M  +1    -1    packages/rkwarddev/man/rkwarddev-package.Rd

http://commits.kde.org/rkward/ebee828b9664556cf6bc6a0bf7ad8da492610f9e

diff --git a/packages/rkwarddev/ChangeLog b/packages/rkwarddev/ChangeLog
index e26f7f7..48169c1 100644
--- a/packages/rkwarddev/ChangeLog
+++ b/packages/rkwarddev/ChangeLog
@@ -1,6 +1,6 @@
 ChangeLog for package rkwarddev
 
-changes in version 0.07-4 (2015-10-26)
+changes in version 0.07-4 (2015-10-27)
 unreleased:
   - this version is under development
 fixed:
@@ -17,10 +17,12 @@ added:
     working rkwarddev script calls
   - new option "ignore" enables rk.uniqueIDs() to not check nodes for
     duplicates (e.g., <copy>)
-  - new wrapper function jo() for id() makes it possible to use several
-    operators without quoting, it will detect and quote them for you
+  - new wrapper function js() for id() makes it possible to use several
+    operators without quoting, preserve "if" conditions and "for" loops,
+    which all will be translated to JavaScript equivalents without the
+    need for quoting
   - new option ".objects" in id() to provide objects as a list
-  - new option "rk.JS.vars" to maje JS varaibles match the name of the
+  - new option "rk.JS.vars" to make JS variables match the name of the
     original R object
 changed:
   - improved error handling in rk.JS.header(), error messages are more
diff --git a/packages/rkwarddev/DESCRIPTION b/packages/rkwarddev/DESCRIPTION
index 6fc4e98..d929a87 100644
--- a/packages/rkwarddev/DESCRIPTION
+++ b/packages/rkwarddev/DESCRIPTION
@@ -8,15 +8,16 @@ Depends:
 Suggests:
     testthat
 Enhances: rkward
-Description: Provides functions to create plugin skeletons and XML structures
-    for RKWard.
+Description: Provides functions to create plugin skeletons and XML
+    structures for RKWard.
 License: GPL (>= 3)
 Encoding: UTF-8
 LazyLoad: yes
 URL: https://rkward.kde.org
-Authors at R: c(person(given="m.eik", family="michalke", email="meik.michalke at hhu.de", role=c("aut", "cre")))
+Authors at R: c(person(given="m.eik", family="michalke",
+        email="meik.michalke at hhu.de", role=c("aut", "cre")))
 Version: 0.07-4
-Date: 2015-10-26
+Date: 2015-10-27
 Collate:
     '00_class_01_rk.JS.arr.R'
     '00_class_02_rk.JS.var.R'
diff --git a/packages/rkwarddev/R/js.R b/packages/rkwarddev/R/js.R
index ef336bc..87445b9 100644
--- a/packages/rkwarddev/R/js.R
+++ b/packages/rkwarddev/R/js.R
@@ -21,12 +21,17 @@
 #' This function is a wrapper for \code{\link[rkwarddev:id]{id}} similar to \code{\link[rkwarddev:qp]{qp}}
 #' that uses \code{eval(substitute(alist(...)))} to preserve the value of \code{...} as-is to be able to
 #' both keep operators like \code{">="} or \code{"!="} unevaluated in the resulting output, as well as translating
-#' \code{if/else} clauses from R to JavaScript.
+#' \code{if/else} clauses and \code{for} loops from R to JavaScript.
 #' 
 #' Normally, \code{id} would simply evaluate the condition and then return the result of that evaluation, which
 #' most of the time is not what you want. With this function, you can test conditions in usual R syntax, yet
 #' the operators and \code{if/else} clauses will end up pasted in the result.
 #' 
+#' Using \code{for} loops is a bit more delicate, as they are very differently constructed in JavaScript. As
+#' a workaround, \code{js} will define an array and a counter variable with randomly generated names, fill
+#' the array with the values you provided and iterate through the array. It will keep the iterator variable
+#' name you used in the original R loop, so you can use it inside the loop body.
+#' 
 #' The following operators are supported: +, -, *, /, ==, !=, >, <, >=, <=, || and &&
 #' 
 #' These are currently unsupported and still need to be quoted: \%, ++, --, =, +=, -=, *=, /=, \%=, ===, !== and !
@@ -62,6 +67,9 @@ js <- function(..., level=2){
         if(inherits(this.part, "if")){
           this.part <- replaceJSIf(this.part, level=level)
         } else {}
+        if(inherits(this.part, "for")){
+          this.part <- replaceJSFor(this.part, level=level)
+        } else {}
         # replace JS operators
         return(do.call("replaceJSOperators", args=list(this.part)))
       } else {
diff --git a/packages/rkwarddev/R/rk-internal.R b/packages/rkwarddev/R/rk-internal.R
index 6c7b3db..21927ba 100644
--- a/packages/rkwarddev/R/rk-internal.R
+++ b/packages/rkwarddev/R/rk-internal.R
@@ -1545,4 +1545,34 @@ replaceJSIf <- function(cond, level=1, paste=TRUE){
     cond <- do.call("js", args=list(cond, level=level))
     return(cond)
   }
-}
+} ## end function replaceJSIf
+
+
+## function replaceJSFor
+replaceJSFor <- function(loop, level=1){
+  if(inherits(loop, "for")){
+    # for loops must be handled differently, we need to create an array
+    # first and then interate through the array to imitate ho R does this
+    # 
+    # also, the array and iterator variables must not be named like any
+    # of the given variables/objects. therefore, we will use some randomly
+    # generated character strings for those
+    arrayName <- paste0("a", paste0(sample(c(letters,LETTERS,0:9), 5, replace=TRUE), collapse=""))
+    iterName <- paste0("i", paste0(sample(c(letters,LETTERS,0:9), 5, replace=TRUE), collapse=""))
+    loop <- paste(
+      paste0(paste0(rep("\t", level-1), collapse=""), "// the following array variable has a randomly generated name"),
+      paste0("var ", arrayName, " = new Array();"),
+      paste0(arrayName, ".push(", do.call("js", args=list(loop[[3]], level=level)), ");"),
+      "// the counter variable also has a randomly generated name",
+      paste0("for (var ", as.character(loop[[2]]), "=", arrayName, "[0], ", iterName, "=0; ",
+        iterName, " < ", arrayName, ".length; ",
+        iterName, "++, ", as.character(loop[[2]]), "=", arrayName, "[", iterName, "]) {"),
+      paste0(paste0(rep("\t", level-1), collapse=""), do.call("js", args=list(uncurl(loop[[4]], level=level+1), level=level))),
+      "}\n",
+      sep=paste0("\n", paste0(rep("\t", level-1), collapse=""))
+    )
+  } else {
+    loop <- do.call("js", args=list(loop, level=level))
+    return(loop)
+  }
+} ## end function replaceJSFor
diff --git a/packages/rkwarddev/R/rkwarddev-package.R b/packages/rkwarddev/R/rkwarddev-package.R
index 1da2349..69008bb 100644
--- a/packages/rkwarddev/R/rkwarddev-package.R
+++ b/packages/rkwarddev/R/rkwarddev-package.R
@@ -4,7 +4,7 @@
 #' Package: \tab rkwarddev\cr
 #' Type: \tab Package\cr
 #' Version: \tab 0.07-4\cr
-#' Date: \tab 2015-10-26\cr
+#' Date: \tab 2015-10-27\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
diff --git a/packages/rkwarddev/inst/NEWS.Rd b/packages/rkwarddev/inst/NEWS.Rd
index 8370b76..8dc2d91 100644
--- a/packages/rkwarddev/inst/NEWS.Rd
+++ b/packages/rkwarddev/inst/NEWS.Rd
@@ -1,7 +1,7 @@
 \name{NEWS}
 \title{News for Package 'rkwarddev'}
 \encoding{UTF-8}
-\section{Changes in rkwarddev version 0.07-4 (2015-10-26)}{
+\section{Changes in rkwarddev version 0.07-4 (2015-10-27)}{
   \subsection{unreleased}{
     \itemize{
       \item this version is under development
@@ -25,10 +25,12 @@
         working rkwarddev script calls
       \item new option \code{"ignore"} enables \code{rk.uniqueIDs()} to not check nodes for
         duplicates (e.g., <copy>)
-      \item new wrapper function \code{jo()} for \code{id()} makes it possible to use several
-        operators without quoting, it will detect and quote them for you
+      \item new wrapper function \code{js()} for \code{id()} makes it possible to use several
+        operators without quoting, preserve \code{"if"} conditions and \code{"for"} loops,
+        which all will be translated to JavaScript equivalents without the
+        need for quoting
       \item new option \code{".objects"} in \code{id()} to provide objects as a list
-      \item new option \code{"rk.JS.vars"} to maje JS varaibles match the name of the
+      \item new option \code{"rk.JS.vars"} to make JS variables match the name of the
         original R object
     }
   }
diff --git a/packages/rkwarddev/man/js.Rd b/packages/rkwarddev/man/js.Rd
index 7500001..f0e3122 100644
--- a/packages/rkwarddev/man/js.Rd
+++ b/packages/rkwarddev/man/js.Rd
@@ -21,7 +21,7 @@ This function is a wrapper for \code{\link[rkwarddev:id]{id}} similar to \code{\
 that uses \code{eval(substitute(alist(...)))} to preserve the value of \code{...} as-is to be able to
 both keep operators like \code{">="} or \code{"!="} unevaluated in the resulting output,
       as well as translating
-\code{if/else} clauses from R to JavaScript.
+\code{if/else} clauses and \code{for} loops from R to JavaScript.
 }
 \details{
 Normally,
@@ -30,6 +30,13 @@ most of the time is not what you want. With this function,
       you can test conditions in usual R syntax, yet
 the operators and \code{if/else} clauses will end up pasted in the result.
 
+Using \code{for} loops is a bit more delicate,
+      as they are very differently constructed in JavaScript. As
+a workaround,
+      \code{js} will define an array and a counter variable with randomly generated names, fill
+the array with the values you provided and iterate through the array. It will keep the iterator variable
+name you used in the original R loop, so you can use it inside the loop body.
+
 The following operators are supported: +, -, *, /, ==, !=, >, <, >=, <=, || and &&
 
 These are currently unsupported and still need to be quoted: \%, ++, --, =, +=, -=, *=,
diff --git a/packages/rkwarddev/man/rkwarddev-package.Rd b/packages/rkwarddev/man/rkwarddev-package.Rd
index 2140e27..30f7f77 100644
--- a/packages/rkwarddev/man/rkwarddev-package.Rd
+++ b/packages/rkwarddev/man/rkwarddev-package.Rd
@@ -12,7 +12,7 @@ A Collection of Tools for RKWard Plugin Development.
 Package: \tab rkwarddev\cr
 Type: \tab Package\cr
 Version: \tab 0.07-4\cr
-Date: \tab 2015-10-26\cr
+Date: \tab 2015-10-27\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



More information about the rkward-tracker mailing list