[rkward-cvs] SF.net SVN: rkward: [1615] trunk/rkward

tfry at users.sourceforge.net tfry at users.sourceforge.net
Sun Mar 18 17:26:44 UTC 2007


Revision: 1615
          http://svn.sourceforge.net/rkward/?rev=1615&view=rev
Author:   tfry
Date:     2007-03-18 10:26:44 -0700 (Sun, 18 Mar 2007)

Log Message:
-----------
Documentation updates

Modified Paths:
--------------
    trunk/rkward/ChangeLog
    trunk/rkward/doc/en/writing_plugins_introduction.docbook

Modified: trunk/rkward/ChangeLog
===================================================================
--- trunk/rkward/ChangeLog	2007-03-18 14:57:35 UTC (rev 1614)
+++ trunk/rkward/ChangeLog	2007-03-18 17:26:44 UTC (rev 1615)
@@ -5,10 +5,10 @@
 - if an incomplete command was piped through the console, the console does not become blocked for piping
 - make "run current line" advance the cursor to next line after running
 - warnings and errors are highlighted in command log / console (warnings only for R >= 2.5.x)
-- plugin generated commands are run in a local() environment, allowing for more consise code		TODO: document, adjust examples, adjust plugins, etc.
+- plugin generated commands are run in a local() environment, allowing for more consise code		TODO: adjust plugins, etc.
 - also support filename completion in the console (mode of completion is determined by heuristic means)
 - initial support for R's Sys.setlocale(), and Encoding of CHARSXPs
-- in help files, a short title for sections (for the navigation bar) can be defined		TODO: document
+- in help files, a short title for sections (for the navigation bar) can be defined
 - the currently active window is now highlighted using a thin red border
 - fixed: changing the type of a column in the data editor was broken
 - fixed: quitting while a plugin was still active would sometimes crash rkward
@@ -29,7 +29,7 @@
 - fixed: plugin browser type="dir" would not work correctly
 - import SPSS and import CSV plugins gain option to open object for editing, automatically (checked by default)
 - warn when opening very large objects (with more than 250000 fields; this limit is configurable)
-- add a "copy" tag to facilitate writing plugins with both dialog and wizard interfaces		TODO: document, convert all wizards to use this
+- add a "copy" tag to facilitate writing plugins with both dialog and wizard interfaces		TODO: convert all wizards to use this
 - fixed: graph previews would stop working when the interface is switched from dialog to wizard or vice versa
 - new options for plugin dialogs: Configure whether code display is shown by default, and at what size
 

Modified: trunk/rkward/doc/en/writing_plugins_introduction.docbook
===================================================================
--- trunk/rkward/doc/en/writing_plugins_introduction.docbook	2007-03-18 14:57:35 UTC (rev 1614)
+++ trunk/rkward/doc/en/writing_plugins_introduction.docbook	2007-03-18 17:26:44 UTC (rev 1615)
@@ -41,8 +41,8 @@
      and in the FDL itself on how to use it. -->
 <legalnotice>&FDLNotice;</legalnotice>
 
-<date>2007-02-01</date>
-<releaseinfo>0.4.6.00</releaseinfo>
+<date>2007-03-18</date>
+<releaseinfo>0.4.7.00</releaseinfo>
 
 <abstract>
 <para>
@@ -63,7 +63,7 @@
 <title>Introduction</title>
 
 <para>
-Documentation as of &kapp; release 0.4.5.
+Documentation as of &kapp; release 0.4.7.
 </para>
 <para>
 This document describes how to write your own plugins. Note, that at the time of this writing, none of the concepts are set it stone. Therefore, this document should be regarded as an introduction to the current approach, and as a basis for discussion. All sorts of comments are welcome.
@@ -284,10 +284,10 @@
 GUI-elements can be organized using a tabbook. Here we define a tabbook as the first element in the dialog. Use <tabbook>[...]</tabbook> to define the tabbook and then for each page in the tabbook use <tab>[...]</tab>. The "label"-attribute in the <tab>-element allows you to specify a caption for that page of the tabbook.
 </para>
 <programlisting>
-				<row>
+				<row id="main_settings_row">
 </programlisting>
 <para>
-The <row> and <column> tags specify the layout of the GUI elements. Here you say, that you'd like to place some elements side-by-side (left to right) and the first of these elements is to be a:
+The <row> and <column> tags specify the layout of the GUI elements. Here you say, that you'd like to place some elements side-by-side (left to right). The "id"-attribute is not strictly necessary, but we'll use it later on, when adding a wizard interface to our plugin. The first element to place in the row, is:
 </para>
 <programlisting>
 					<varselector id="vars"/>
@@ -348,10 +348,10 @@
 By default elements will be placed top-to-bottom like in a <column>. Since that is what we want here, we don't have to explicitly state a <row> or <column>-layout. The first element we define is a checkbox. Just like the <radio><option>s, the checkbox has a "label" and a "value". The "value" is what gets returned, if the checkbox is checked. Of course the checkbox also needs an "id".
 </para>
 <programlisting>
-				<frame label="Confidence Interval">
+				<frame label="Confidence Interval" id="frame_conf_int">
 </programlisting>
 <para>
-Here's yet another layout-element: In order to signal that the two elements below  belong together, we draw a <frame> (box). That frame may have a caption. Since the frame is just a passive layout-element, it does not need an "id".
+Here's yet another layout-element: In order to signal that the two elements below  belong together, we draw a <frame> (box). That frame may have a caption. Since the frame is just a passive layout-element, it does not need an "id", we still define one, here, as we'll refer to it later, when defining an additional wizard interface.
 </para>
 <programlisting>
 					<checkbox id="confint" label="print confidence interval" value="1" checked="true"/>
@@ -367,67 +367,69 @@
 	</dialog>
 </programlisting>
 <para>
-That's all for the second page of the <tabbook>, all pages in the <tabbook> and all elements in the <dialog>. We're finished defining what the dialog looks like. Actually we don't have to define an additional <wizard>-interface, but here's how that would be done. Things should be fairly self-explanatory be now, so I leave that part without comments:
+That's all for the second page of the <tabbook>, all pages in the <tabbook> and all elements in the <dialog>. We're finished defining what the dialog looks like.
 </para>
 <programlisting>
-	<wizard label="Independent Samples T-Test">
-		<page id="firstpage">
-			<text>As a first step, select the two variables you want to compare against each other. And specify, which one you theorize to be greater. Select two-sided, if your theory does not tell you, which variable is greater.</text>
-			<row>
-				<column>
-					<varselector id="vars"/>
-				</column>
-				<column>
-					<varslot type="numeric" id="x" source="vars" required="true" label="compare"/>
-					<varslot type="numeric" id="y" source="vars" required="true" label="against"/>
-					<radio id="hypothesis" label="using test hypothesis">
-						<option value="two.sided" label="Two-sided"/>
-						<option value="greater" label="First is greater"/>
-						<option value="less" label="Second is greater"/>
-					</radio>
-				</column>
-			</row>
-		</page>
-		<page id="secondpage">
-			<text>Below are some advanced options. It's generally safe not to assume the variables have equal variances. An appropriate correction will be applied then. Chosing "assume equal variances" may increase test-strength, however.</text>
-			<checkbox id="varequal" label="assume equal variances" value=", var.equal=TRUE"/>
-			<text>Sometimes it's helpful to get an estimate of the confidence interval of the difference in means. Below you can specify whether one should be shown, and which confidence-level should be applied (95% corresponds to a 5% level of significance).</text>
-			<frame label="Confidence Interval">
-				<checkbox id="confint" label="print confidence interval" value="1" checked="true"/>
-				<spinbox type="real" id="conflevel" label="confidence level" min="0" max="1" initial="0.95"/>
-			</frame>
-		</page>
-	</wizard>
-</programlisting>
-<para>
-As you see, all of this is mostly a duplication of what has been defined for the dialog-interface. You may of course make the wizard-interface look very different to the plain dialog. Be sure, however, to assign corresponding elements the same "id" in both interfaces. This is not only used to transfer settings from the dialog-interface to the wizard-interface and back, when the user switches interfaces (which does not yet happen in the current version of RKWard), but also simplifies writing your code-template (see below). 
-</para>
-<programlisting>
 </document>
 </programlisting>
 <para>
-Finally we close the <document>-tag, and that's it. The GUI is defined. You can save the file now. But how does R-syntax get generated from the GUI-settings? I'll deal with that in the <link linkend="phptemplate">next chapter</link>.
+Finally we close the <document>-tag, and that's it. The GUI is defined. You can save the file now.
+But how does R-syntax get generated from the GUI-settings? I'll deal with that in the <link linkend="phptemplate">next chapter</link>. First, however, we'll look into adding a wizard interface, and some general considerations.
 </para>
 
-<section id="mainxmltips">
-<title>Some considerations on GUI design</title>
-<para>
-This section contains some general considerations on which GUI elements to use where. If this is your first attempt of creating a plugin, feel free to skip over this section, as it isn't relevant to getting a basic GUI working. Come back here, later, to see, whether you can refine your plugin's GUI in some way or another.
-</para>
-
-<section id="radio_vs_checkbox_vs_dropdown">
-<title><radio> vs. <checkbox> vs. <dropdown></title>
-<para>
-The three elements <radio>, <checkbox>, <dropdown>, all serve a similar function: To select one out of a several options. Obviously, a checkbox only allows to chose between two options: checked or not checked, so you can't use it, if there are more than two options to chose from. But when to use which of the elements? Some rules of thumb:
-</para>
-<para>
-If you find yourself creating a <radio> or <dropdown> with only two options, ask yourself, whether the question is essentially a yes / no type of question. E.g. a choice between "adjust results" and "do not adjust results", or between "remove missing values" and "keep missing values". In this case a <checkbox> is the best choice: It uses little space, will have the least words of labels, and is easiest to read for the user. There are very few situations where you should chose a <radio> over a <checkbox>, when there are only two options. An example of that might be: "Method of calculation: 'pearson'/'spearman'". Here, more methods might be thinkable, and they don't really form a pair of opposites.
-</para>
-<para>
-Chosing between a <radio> and a <dropdown> is mostly a question of space. The <dropdown> has the advantage of using little space, even if there are a lot of options to chose from. On the other hand, a <radio> has the advantage of making all possible choices visible to the user at once, without clicking on the dropdown arrow. Generally, if there are six or more options to chose from, a <dropdown> is preferrable. If there are five or less options, a <radio> is the better choice.
-</para>
+<section id="wizard_interface">
+	<title>Adding a wizard interface</title>
+	<para>
+	Actually we don't have to define an additional <wizard>-interface, but here's how that would be done. To add a wizard interface, you'll add a <wizard> tag at the same level as the <dialog> tag:
+	</para>
+	<programlisting>
+		<wizard label="Independent Samples T-Test">
+			<page id="firstpage">
+				<text>As a first step, select the two variables you want to compare against each other. And specify, which one you theorize to be greater. Select two-sided, if your theory does not tell you, which variable is greater.</text>
+				<copy id="main_settings_row/>
+			</page>
+	</programlisting>
+	<para>
+	Some of this is pretty self explanatory: We add a <wizard> tag with a label for the wizard. Since a wizard can hold several pages that are shown one after another, we next define the first page, and put an explanatory text note in there. Then we use a <copy>-tag. What this does, is really it saves us having to define yet again, what we already wrote for the <dialog>: The copy tag looks for another tag with the same "id" earlier in the .xml. This happens to be defined in the <dialog> section, and is a <row> in which there are the <varselector>, <varslots> and the "hypothesis" <radio>-control. All of this is copied 1:1 and inserted right at the <copy> element.
+	</para>
+	<para>
+	Now to the second page:
+	</para>
+	<programlisting/>
+			<page id="secondpage">
+				<text>Below are some advanced options. It's generally safe not to assume the variables have equal variances. An appropriate correction will be applied then. Chosing "assume equal variances" may increase test-strength, however.</text>
+				<copy id="varequal"/>
+				<text>Sometimes it's helpful to get an estimate of the confidence interval of the difference in means. Below you can specify whether one should be shown, and which confidence-level should be applied (95% corresponds to a 5% level of significance).</text>
+				<copy id="frame_conf_int"/>
+			</page>
+		</wizard>
+	</programlisting>
+	<para>
+	Much of the same thing here. We add some texts, and in between that <copy> further sections from the dialog interface.
+	</para>
+	<para>
+	You may of course make the wizard-interface look very different to the plain dialog, and not use the <copy> tag at all. Be sure, however, to assign corresponding elements the same "id" in both interfaces. This is not only used to transfer settings from the dialog-interface to the wizard-interface and back, when the user switches interfaces (which does not yet happen in the current version of RKWard), but also simplifies writing your code-template (see below). 
+	</para>
 </section>
 
+<section id="mainxmltips">
+	<title>Some considerations on GUI design</title>
+	<para>
+	This section contains some general considerations on which GUI elements to use where. If this is your first attempt of creating a plugin, feel free to skip over this section, as it isn't relevant to getting a basic GUI working. Come back here, later, to see, whether you can refine your plugin's GUI in some way or another.
+	</para>
+	
+	<section id="radio_vs_checkbox_vs_dropdown">
+		<title><radio> vs. <checkbox> vs. <dropdown></title>
+		<para>
+		The three elements <radio>, <checkbox>, <dropdown>, all serve a similar function: To select one out of a several options. Obviously, a checkbox only allows to chose between two options: checked or not checked, so you can't use it, if there are more than two options to chose from. But when to use which of the elements? Some rules of thumb:
+		</para>
+		<para>
+		If you find yourself creating a <radio> or <dropdown> with only two options, ask yourself, whether the question is essentially a yes / no type of question. E.g. a choice between "adjust results" and "do not adjust results", or between "remove missing values" and "keep missing values". In this case a <checkbox> is the best choice: It uses little space, will have the least words of labels, and is easiest to read for the user. There are very few situations where you should chose a <radio> over a <checkbox>, when there are only two options. An example of that might be: "Method of calculation: 'pearson'/'spearman'". Here, more methods might be thinkable, and they don't really form a pair of opposites.
+		</para>
+		<para>
+		Chosing between a <radio> and a <dropdown> is mostly a question of space. The <dropdown> has the advantage of using little space, even if there are a lot of options to chose from. On the other hand, a <radio> has the advantage of making all possible choices visible to the user at once, without clicking on the dropdown arrow. Generally, if there are six or more options to chose from, a <dropdown> is preferrable. If there are five or less options, a <radio> is the better choice.
+		</para>
+	</section>	
 </section>
 
 </chapter>
@@ -447,24 +449,24 @@
 This is a sort of opening tag in PHP. Everything between <? and ?> will be interpreted as PHP-code. Everything outside of these tags will simply be returned as plain text. See below for examples.
 </para>
 <programlisting>
-	function preprocess () {
-	}
+function preprocess () {
+}
 </programlisting>
 <para>
 The PHP-file is organized into four separate functions: preprocess, calculate, printout and cleanup. This is because not all code is needed at all stages. Currently the preprocess-function is not really used.
 </para>
 <programlisting>
-	function calculate () {
-?>rk.temp <- t.test (<? getRK ("x"); ?>, <? getRK ("y"); ?>, "<? getRK ("hypothesis"); ?>"<? getRK ("varequal"); if (($conflevel = getRK_val ("conflevel")) != "0.95") echo (", conf.level=" . $conflevel); ?>)
+function calculate () {
+?>res <- t.test (<? getRK ("x"); ?>, <? getRK ("y"); ?>, "<? getRK ("hypothesis"); ?>"<? getRK ("varequal"); if (($conflevel = getRK_val ("conflevel")) != "0.95") echo (", conf.level=" . $conflevel); ?>)
 <?
-	}
+}
 </programlisting>
 <para>
 This function generates the actual R-syntax to be run from the GUI-settings. Let's look at this in detail:
 First we leave the PHP-mode (?>) and hence return
 </para>
 <screen>
-rk.temp <- t.test (
+res <- t.test (
 </screen>
 <para>
 as plain text. Next we need to fill in the value, the user selected as the first variable. Hence we enter PHP-mode again (<?) and call 'getRK ("x");'. This prints out the value of the GUI-element with id "x": our first <varslot>. Next we leave PHP-mode again, print a ', ', and do the same to fetch the value of the element "y" - the second <varslot>. For the hypothesis (the <radio>-group), and the equal variances-<checkbox>, the procedure is very similar.
@@ -474,21 +476,21 @@
 Finally, we leave PHP-mode again, print a last ')', and that's it for the calculate-function.
 </para>
 <programlisting>
-	function printout () {
+function printout () {
 ?>rk.header ("Independent samples t test")
-rk.print (rk.temp)
+rk.print (res)
 <?
-	}
+}
 </programlisting>
 <para>
 And this was all there is to the printout function in most cases. rk.header () prints a standard headline for the results. You can also add some more information to this, if you like, e.g.:
 </para>
 <programlisting>
-	function printout () {
+function printout () {
 ?>rk.header ("Independent samples t test", parameters=list ("Assume equal variances", <? getRK ("varequal"); ?>, "Confidence level", <? getRK ("conflevel"); ?>))
-rk.print (rk.temp)
+rk.print (res)
 <?
-	}
+}
 </programlisting>
 <para>
 The list of parameters is given as pairs of "Description", "Value". This will also be printed in a standard way.
@@ -499,37 +501,24 @@
 <para>
 Note that internally, the output is just a plain HTML document at this point of time. Therefore you might be tempted to add custom HTML using cat (). While this will work, please don't do this. The output format may change (e.g. to ODF) in the future, so it's best not to introduce HTML specific code. Rather keep things simple with rk.header (), rk.print (), and rk.results (). If those don't seem to satisfy your formatting needs, contact us on the mailing list for help.
 </para>
-<programlisting>
-	function cleanup () {
-?>rm (rk.temp)
-<?
-	}
-?>
-</programlisting>
 <para>
-Finally, in the function cleanup we discard the temporary object(s) we left in the R-workspace. You should always clean up all objects created while running the plugin, except if the user explicitely requested otherwise.
-</para>
-<para>
 Congratulations! You created your first plugin. Read on in the next chapters for more advanced concepts.
 </para>
 
 <section id="phpconventions">
-<title>Conventions and policies</title>
+<title>Conventions, policies, and background</title>
 <para>
-There are many ways to write R code for a certain task, and there are even more ways to generate this R code from PHP. How exactly you do it, is left up to you. Still there are a number of considerations that you should follow.
+There are many ways to write R code for a certain task, and there are even more ways to generate this R code from PHP. How exactly you do it, is left up to you. Still there are a number of considerations that you should follow, and background information you should understand.
 </para>
 
-<section id="policyvariablenaming">
-<title>Variable naming</title>
+<section id="policylocal">
+<title>Understanding the local() environment</title>
 <para>
-More often than not you will have to create one or more temporary R objects in the code generated by your plugin. When doing so, please name all objects rk.tempX, where X can be any name you like. So, just prefix the variable names with "rk.temp".
+More often than not you will have to create one or more temporary R objects in the code generated by your plugin. Normally, you do not want those to be placed in the user's workspace, potentially even overwriting user variables. Hence, all plugin generated code is run in a local() environment (see R help page on function local()). This means, all variables you create are temporary and will not be saved permanently.
 </para>
 <para>
-The reason for this policy is, that plugin code is executed directly in the user's R workspace. If an object happens to be left over (because there was an error, or you forgot to state it the in cleanup () section), it should not be easy to confuse with the other objects the user has. More importantly, if the user has a symbol "x" in the workspace, and you name a variable "x" in your plugin, the user's variable will be overwritten without prompting! Obviously this should be strictly avoided.
+If the user explicitely asks for a variable to be saved, you will need to assign to that object with the "<<-" operator.
 </para>
-<para>
-One exception to this rule is, that if the user explicitely asked for an object to be stored in the workspace, that is ok, of course.
-</para>
 </section>
 
 <section id="policyformatting">
@@ -551,16 +540,16 @@
 </para>
 <programlisting>
 # first determine the wobble and rotation
-rk.temp.wobble <- wobble (x, y)
-rk.temp.rotation <- wobble.rotation (wobble, z)
+my.wobble <- wobble (x, y)
+my.rotation <- wobble.rotation (my.wobble, z)
 
 # boggling method needs to be chosen according to rotation
-if (rk.temp.rotation > wobble.rotation.limit (x)) {
-	rk.temp.method <- "foo"
-	rk.temp.result <- boggle.foo (rk.temp.wobble, rk.temp.rotation)
+if (my.rotation > wobble.rotation.limit (x)) {
+	method <- "foo"
+	result <- boggle.foo (my.wobble, my.rotation)
 } else {
-	rk.temp.method <- "bar"
-	rk.temp.result <- boggle.bar (rk.temp.wobble, rk.temp.rotation)
+	method <- "bar"
+	result <- boggle.bar (my.wobble, my.rotation)
 }
 </programlisting>
 </section>
@@ -571,21 +560,21 @@
 Many plugins can do more than one thing. For instance, the "Descriptive Statistics" plugin can compute mean, range, sum, product, median, length, etc. However, typically the user will only chose to have some of those calculations performed. In this case, please try to keep the generated code as simple as possible. It should only contain portions relevant to the options that are actually selected. To achieve this, here is an example of a common design patterns as you would use it (in PHP):
 </para>
 <programlisting>
-	function calculate () { ?>
-rk.temp.var <- <? getRK ("x");
-rk.temp.results <- list () ?>
+function calculate () { ?>
+x <- <? getRK ("x");
+results <- list () ?>
 <?
-		if (getRK_val ("domean")) { ?>
-rk.temp.results$'Mean value' <- mean (rk.temp.var)
-<?		}
-		if (getRK_val ("domedian")) { ?>
-rk.temp.results$'Median' <- median (rk.temp.var)
-<?		}
-		if (getRK_val ("dosd")) { ?>
-rk.temp.results$'Standard deviation' <- sd (rk.temp.var)
-<?		}
-		//...
-	}
+	if (getRK_val ("domean")) { ?>
+results$'Mean value' <- mean (x)
+<?	}
+	if (getRK_val ("domedian")) { ?>
+results$'Median' <- median (x)
+<?	}
+	if (getRK_val ("dosd")) { ?>
+results$'Standard deviation' <- sd (x)
+<?	}
+	//...
+}
 </programlisting>
 </section>
 
@@ -608,9 +597,9 @@
 	}
 ?>
 # ...
-rk.temp.results$foo <- foo (rk.temp.x<? echo ($narm); ?>)
-rk.temp.results$bar <- bar (rk.temp.x<? echo ($narm); ?>)
-rk.temp.results$foobar <- foobar (rk.temp.x<? echo ($narm); ?>)
+results$foo <- foo (x<? echo ($narm); ?>)
+results$bar <- bar (x<? echo ($narm); ?>)
+results$foobar <- foobar (x<? echo ($narm); ?>)
 # ...
 <?
 }
@@ -1048,10 +1037,13 @@
 The usage section is always the second section shown in a help page.
 	</usage>
 
-	<section id="sectionid" title="Generic section">
+	<section id="sectionid" title="Generic section" short_title="Generic">
 If you need to, you can add additional sections between the usage and settings sections.
 However, usually, you will not need this while documenting plugins. The "id"-attribute
-provides an anchor point to jump to this section from the navigation menu.
+provides an anchor point to jump to this section from the navigation menu. The "short_title"
+attribute provides a short title to use in the navigation bar. This is optional, by default
+the main "title" will be used both as a heading to the section, and as the link name in the
+navigation bar.
 
 In any section you may want to insert links to further information. You do this by adding
 
@@ -1233,6 +1225,20 @@
 	</varlistentry>
 	</variablelist></listitem>
 </varlistentry>
+<varlistentry>
+<term><copy></term>
+<listitem>Can be used as a child (direct or indirect) of the main layout elements, i.e. <dialog> and <wizard>. This is used to copy an entire block a xml elements 1:1. Attributes:
+	<variablelist>
+	<varlistentry>
+	<term><id></term>
+	<listitem>The id to look for. The <copy> tag will look for a previous XML element that has been given the same id, and copy it including all descendent elements.</listitem>
+	</varlistentry>
+	<varlistentry>
+	<term><copy_element_tag_name></term>
+	<listitem>In some few cases, you will want an almost literal copy, but change the tag-name of the element to copy. The most important example of this is, when you want to copy an entire <tab> from a dialog interface to the <page> of a wizard interface. In this case, you'd set coyp_elemnent_tag_name="page" to do this conversion automatically.</listitem>
+	</varlistentry>
+	</variablelist></listitem>
+</varlistentry>
 </variablelist>
 </section>
 


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