[rkward-cvs] SF.net SVN: rkward:[4119] trunk/rkward/packages/rkwarddev/inst/doc

m-eik at users.sourceforge.net m-eik at users.sourceforge.net
Tue Dec 13 21:53:54 UTC 2011


Revision: 4119
          http://rkward.svn.sourceforge.net/rkward/?rev=4119&view=rev
Author:   m-eik
Date:     2011-12-13 21:53:53 +0000 (Tue, 13 Dec 2011)
Log Message:
-----------
rkwarddev: the vignette starts to become useful...

Modified Paths:
--------------
    trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.Rnw
    trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.pdf

Modified: trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.Rnw
===================================================================
--- trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.Rnw	2011-12-13 18:36:59 UTC (rev 4118)
+++ trunk/rkward/packages/rkwarddev/inst/doc/rkwarddev_vignette.Rnw	2011-12-13 21:53:53 UTC (rev 4119)
@@ -104,8 +104,27 @@
 but rather explain the basic steps to create a plugin ''the \texttt{rkwarddev} way`` in general. While doing that, we'll explore some of the alternative options
 you have when using different functions.
 
-Some of them might not be so obvious at first, but I believe that once you know them, you'll learn to like them, too.
+Some of them might not be so obvious at first, but I believe that once you know them, you'll learn to like them, too. The basic steps to write a plugin using this
+package can be summarized this way:
 
+\begin{enumerate}
+	\item Know how the \texttt{R} code works you want to generate with the plugin in the end
+	\item Have an idea what the dialog should look like (e.\,g., a varselector left, a varslot and two checkboxes right, etc.)
+	\item Use \texttt{rkwarddev} functions to
+	\begin{enumerate}
+		\item create XML objects for each of these dialog elements individually
+		\item combine these individual objects to one dialog object
+		\item create JavaScript objects (using the XML objects) responsible for the \texttt{R} code of the finished plugin
+		\item create logic, wizard, ... objects the same way
+		\begin{itemize}
+			\item maybe also create help files objects
+		\end{itemize}
+		\item combine all the dialog, logic, wizard, JavaScript ... objects into one plugin and have it written to disk (the plugin map will be generated almost by itself)
+	\end{enumerate}
+\end{enumerate}
+
+So you start with individual parts (the widget elements), combine them, combine what you combined, and so forth. 
+
 To begin with some background info, this package makes use of another \texttt{R} package I wrote, called
 \texttt{XiMpLe}\footnote{\url{http://reaktanz.de/?c=hacking\&s=XiMpLe}}. It is a \textit{very} simple XML parser/generator, hence its name.
 All \texttt{rkwarddev} functions dealing with XML utilize tools of this package, that is, the XML objects created are most likely of class
@@ -113,7 +132,6 @@
 are all part of \texttt{rkwarddev} itself.}
 
 \subsection{What you see is what you get, in the end}
-
 Both packages also come with \texttt{show} methods for their objects. This means that the object you create and how it looks when called
 in an R session are not the same: What you will see in your terminal is what the object \textit{would} look like if you \textit{pasted} it
 to a file, using the \texttt{paste} functions of the packages:
@@ -164,8 +182,8 @@
 		\end{Sinput}
 		\begin{Soutput}
 <frame label="Example XML object" id="frm_ExmplXML">
-	<checkbox id="chc_Checkme" label="Check me!" value="true" />
-	<checkbox id="chc_Nocheckm" label="No, check me!!!" value="true" checked="true" />
+  <checkbox id="chc_Checkme" label="Check me!" value="true" />
+  <checkbox id="chc_Nocheckm" label="No, check me!!!" value="true" checked="true" />
 </frame>
 		\end{Soutput}
 	\end{Schunk}
@@ -229,6 +247,257 @@
 
 This context dependent object handling will become even more useful when we get to the JavaScript part.
 
+\subsubsection{From single elements to a dialog}
+Once you have an idea which elements you would like to see in your dialog, and have also created individual XML objects of them, you finally have to
+put them all together to form the full dialog XML. This is done by \texttt{rk.XML.dialog()}, in the same manner that \texttt{rk.XML.frame()} was used.
+To get the layout into the desired structure, use \texttt{rk.XML.row()} and \texttt{rk.XML.col()} to group elements into rows and columns, as nested
+as you see fit:
+
+	\begin{Schunk}
+		\begin{Sinput}
+> (myDialog <- rk.XML.dialog(
++   rk.XML.row(
++     myVarselector,
++     rk.XML.col(myVars, myFrame)),
++   label="Example dialog"))
+		\end{Sinput}
+		\begin{Soutput}
+<dialog label="Example dialog">
+  <row id="row_vCCEXMLEXM">
+    <varselector id="my_vars" />
+    <column id="clm_vCCEXMLEXM">
+      <varslot id="vrsl_Chosvrbl" label="Chose a variable" source="my_vars" />
+      <frame label="Example XML object" id="frm_ExmplXML">
+        <checkbox id="chc_Checkme" label="Check me!" value="true" />
+        <checkbox id="chc_Nocheckm" label="No, check me!!!" value="true" checked="true" />
+      </frame>
+    </column>
+  </row>
+</dialog>
+		\end{Soutput}
+	\end{Schunk}
+
+Now, wouldn't it be nice to see how that looks like in \texttt{RKWard}? Well, you can:
+
+	\begin{Schunk}
+		\begin{Sinput}
+> rk.plugin.skeleton(
++   about="Example plugin",
++   xml=list(dialog=myDialog),
++   load=TRUE,
++   show=TRUE
++ )
+		\end{Sinput}
+		\begin{Soutput}
+For filenames ‘Example plugin’ was renamed to ‘Exampleplugin’.
+Created directory /tmp/Rtmp9gdThb/Exampleplugin.
+Created directory /tmp/Rtmp9gdThb/Exampleplugin/R.
+Created directory /tmp/Rtmp9gdThb/Exampleplugin/inst/rkward/plugins.
+Created directory /tmp/Rtmp9gdThb/Exampleplugin/inst/rkward/tests/Exampleplugin.
+For filenames ‘Example plugin’ was renamed to ‘Exampleplugin’.
+For filenames ‘Example plugin’ was renamed to ‘Exampleplugin’.
+For filenames ‘Example plugin’ was renamed to ‘Exampleplugin’.
+For filenames ‘Example plugin’ was renamed to ‘Exampleplugin’.
+[1] "/tmp/Rtmp9gdThb/Exampleplugin"
+		\end{Soutput}
+	\end{Schunk}
+
+Allthough until now all we did was to outline the XML description of our plugin-to-become, \texttt{rkwarddev}
+can already generate a full plugin. \texttt{load=TRUE} makes sure that \texttt{RKWard} recognizes the new plugin
+immediately after it was created, and \texttt{show=TRUE} will even make it pop up, too:
+
+\begin{center}
+ \includegraphics{./RKWard_vign_example_dialog_wcode.png}
+ % RKWard_vign_example_dialog_wcode.png: 423x407 pixel, 99dpi, 10.85x10.44 cm, bb=0 0 308 296
+\end{center}
+
+Not bad for less than 20 short lines of code. This makes dialog design both very efficient and flexible:
+Imagine you want to re-arrange the order of elements, or experiment with completely different tabbook layouts, all you need to
+do is to change the \texttt{rk.XML.dialog()} call and run \texttt{rk.plugin.skeleton()} again (with \texttt{overwrite=TRUE}).
+If you don't specify a directory explicitly, all will be written to a temporary directory. As seen in the example output,
+the return value of \texttt{rk.plugin.skeleton()} is allways the root directory of the created plugin.
+
+Looking at the attribute \texttt{xml=list(dialog=myDialog)}, we can assume that
+
+\begin{enumerate}
+	\item there's more than a \texttt{dialog} we can provide\\
+		\textit{Further valid options are \texttt{wizard}, \texttt{logic} and \texttt{snippets}}
+	\item there's more to define than just the \texttt{xml} of a plugin
+		\textit{Further arguments include \texttt{js}, \texttt{pluginmap}, \texttt{rkh} and \texttt{components}, among others}
+\end{enumerate}
+
+Of course, this plugin doesn't really do anything useful. In fact, it doesn't matter how you treat the buttons and boxes, the R code below
+won't change a bit, because we didn't provide any JavaScript code to deal with those events.
+
+\subsection{Generating JavaScript code}
+In contrast to what we've seen with the XML code, where objects are nested into others and the result is one big XML object, generated JavaScript code
+is always a plain character string in the end. This is because it doesn't make much sense to treat a programming language otherwise, if you don't want
+to lose its flexibility. But in between, existing objects will be re-used and new ones created as well. The best way to understand how \texttt{rkwarddev}
+handles the JavaScript part is to think of it as a specialized \texttt{paste()}. Its special feature is that it understands the objects we're dealing
+with, and depending on where they occur, knows what strings to make out of them.
+
+Therefore, the most direct approach to get JavaScript into the plugin would to write it all by hand, paste it into a character object and give that to
+\texttt{rk.plugin.skeleton()}. But again, \texttt{rkwarddev} offers some helpful tools.
+
+\subsubsection{Defining variables}
+We just created the XML dialog, which in turn of course includes all the elements (and their IDs) we need to care about. Or the other way round:
+For each element in the dialog it is pretty safe to assume that it should have \textit{some} effect on the outcome. So for a start, \texttt{rkwarddev}
+can ''scan`` the dialog object\footnote{In fact, \texttt{rk.JS.scan()} is not limited to R objects but can also read XML files.},
+collect all relevant IDs and define them as JavaScript variables automatically. Try this for a demonstration:
+
+	\begin{Schunk}
+		\begin{Sinput}
+> cat(rk.JS.scan(myDialog))
+		\end{Sinput}
+		\begin{Soutput}
+  var vrslChosvrbl = getValue("vrsl_Chosvrbl");
+  var chcCheckme = getValue("chc_Checkme");
+  var chcNocheckm = getValue("chc_Nocheckm");
+		\end{Soutput}
+	\end{Schunk}
+
+Notice that only the varslot and both checkboxes show up -- \texttt{rk.JS.scan()} distinguishes between relevant and irrelevant IDs, e.\,g. a
+row or column is no GUI element of interest here. By the way, if you defined the frame as \texttt{checkable=TRUE}, its ID would be
+extracted as well.\footnote{There is also a related function called \texttt{rk.JS.saveobj()}, which scans for \texttt{<saveobject>} nodes and
+does not only define the neccessary variables, but also generates the full JavaScript code snippet for the \texttt{printout()} function,
+to effectively save result objects to workspace.}
+
+You might also notice that the JavaScript variable names differ from the XML IDs. For once, that way they're harder to confuse with each other,
+and there's also some conventions which characters are allowed. But to cut things short, we don't have to worry about the variable names,
+just like we didn't have to care about the XML IDs before. We don't even have to call \texttt{rk.JS.scan()} ourselves, as
+\texttt{rk.plugin.skeleton()} will do so where appropriate, if the option \texttt{scan} includes \texttt{"var"}, which by default is the case.
+
+This means, once more we can concentrate on what the plugin shall actually do, perhaps some calculation of a kind.
+
+\subsubsection{Shortcut functions}
+The common task here is to check for certain dialog events (like unchecking the checkbox labelled ''foo``), and then generate the according
+\texttt{R} code (like \texttt{foo=FALSE}). The question remains, if we don't know the actual variable names, how can we check for events
+of certain dialog elements in the JavaScript code? The answer to that is: We generate the code using \texttt{rkwarddev}'s special
+JavaScripting functions and paste it with \texttt{rk.paste.JS()}. That way, we can use the created XML objects once again, as reference
+to which element we actually mean.
+
+\paragraph{echo()}
+The JavaScript equivalent to \texttt{paste()} is \texttt{echo()}, with a slightly different
+syntax: Concatenation is not done by commas, but by the plus sign, and the line must end with a semicolon. This is an example why it might be
+nice to not need to switch between languages back and forth any more. So \texttt{rkwarddev} has an \texttt{R} function called \texttt{echo()},
+which translates \texttt{paste()}-like arguments into an equivalent JavaScript call:
+
+	\begin{Schunk}
+		\begin{Sinput}
+> echo("# Value of the checkbox is: ", myCheckbox, "\n")
+		\end{Sinput}
+		\begin{Soutput}
+[1] "echo(\"# Value of the checkbox is: \" + chcCheckme + "\n");"
+		\end{Soutput}
+	\end{Schunk}
+
+If this JavaScript code line was used, it would simply add a comment regarding the checkbox value to the \texttt{R} code,
+including a newline.
+
+\paragraph{ite()}
+Now we know how to paste JavaScript code which echoes \texttt{R} code. What we definitely need at some point is \texttt{if()} conditions. For
+that, \texttt{rkwarddev} offers \texttt{ite()}. The function takes up to three arguments: One ''if`` condition, one ''then`` action, and optionally
+one ''else`` action. But actually, neither will the ''if`` condition be evaluated, nor will any of the actions be taken. The arguments just
+define what should be \textit{pasted} at which part if the conditional statement:
+
+	\begin{Schunk}
+		\begin{Sinput}
+> ite("foo", "bar", "baz")
+		\end{Sinput}
+		\begin{Soutput}
+  if(foo) {
+    bar
+  } else {
+    baz
+  }
+		\end{Soutput}
+	\end{Schunk}
+
+However, in contrast to \texttt{echo()}, what \texttt{ite()} returns is not a character string, but similar to what we've seen with the XML
+functions a special JavaScript object. Amongst other things, this is useful to again generate readable code, e.\,g. nested conditions:
+
+	\begin{Schunk}
+		\begin{Sinput}
+> ite(myCheckbox,
++   ite(myVars,
++     echo("result <- ", myVars, "\n"),
++     echo("# huh?\n")
++   ),
++   ite(myCheckbox2,
++     echo("## ouch!\n")
++   )
++ )
+		\end{Sinput}
+		\begin{Soutput}
+  if(chcCheckme) {
+    if(vrslChosvrbl) {
+      echo("result <- " + vrslChosvrbl + "\n");
+    } else {
+      echo("# huh?\n");
+    }
+  } else if(chcNocheckm) {
+    echo("## ouch!\n");
+  } else {}
+		\end{Soutput}
+	\end{Schunk}
+
+To finally use this object in the plugin, it must be evaluated and transformed into a character string.
+
+\paragraph{rk.paste.JS()}
+This is where \texttt{rk.paste.JS()} comes into play:
+
+	\begin{Schunk}
+		\begin{Sinput}
+> myCalculation <- rk.paste.JS(
++   ite(myCheckbox,
++     ite(myVars,
++       echo("result <- ", myVars, "\n"),
++       echo("# huh?\n")
++     ),
++     ite(myCheckbox2,
++       echo("## ouch!\n")
++     )
++   )
++ )
++ rk.plugin.skeleton(
++   about="Example plugin",
++   xml=list(dialog=myDialog),
++   js=list(calculate=myCalculation),
++   load=TRUE,
++   show=TRUE,
++   overwrite=TRUE
++ )
+		\end{Sinput}
+		\begin{Soutput}
+For filenames 'Example plugin' was renamed to 'Exampleplugin'.
+For filenames 'Example plugin' was renamed to 'Exampleplugin'.
+For filenames 'Example plugin' was renamed to 'Exampleplugin'.
+For filenames 'Example plugin' was renamed to 'Exampleplugin'.
+For filenames 'Example plugin' was renamed to 'Exampleplugin'.
+[1] "/tmp/Rtmp9gdThb/Exampleplugin"
+		\end{Soutput}
+	\end{Schunk}
+
+Now the plugin actually changes the generated code of you select an object from the workspace and toggle the checkboxes:
+
+\begin{center}
+ \includegraphics{./RKWard_vign_example_dialog_wcode_JS.png}
+ % RKWard_vign_example_dialog_wcode_JS.png: 763x453 pixel, 99dpi, 19.57x11.62 cm, bb=0 0 555 329
+\end{center}
+
+% \subsection{The whole is more than the sum of its parts}
+% 
+% 
+% 
+% 	\begin{Schunk}
+% 		\begin{Sinput}
+% s
+% 		\end{Sinput}
+% 		\begin{Soutput}
+% s
+% 		\end{Soutput}
+% 	\end{Schunk}
+
 %  \begin{Schunk}
 %  	\begin{Sinput}
 %  	\end{Sinput}

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

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