[rkward-cvs] SF.net SVN: rkward:[3941] trunk/rkward/doc/rkwardplugins/index.docbook
m-eik at users.sourceforge.net
m-eik at users.sourceforge.net
Fri Oct 14 14:20:22 UTC 2011
Revision: 3941
http://rkward.svn.sourceforge.net/rkward/?rev=3941&view=rev
Author: m-eik
Date: 2011-10-14 14:20:22 +0000 (Fri, 14 Oct 2011)
Log Message:
-----------
further markup improvements in writing plugins docs
Modified Paths:
--------------
trunk/rkward/doc/rkwardplugins/index.docbook
Modified: trunk/rkward/doc/rkwardplugins/index.docbook
===================================================================
--- trunk/rkward/doc/rkwardplugins/index.docbook 2011-10-14 07:41:02 UTC (rev 3940)
+++ trunk/rkward/doc/rkwardplugins/index.docbook 2011-10-14 14:20:22 UTC (rev 3941)
@@ -74,342 +74,358 @@
<chapter id="introduction">
<title>Introduction</title>
-<para>
-Documentation as of &rkward; release 0.5.7.
-</para>
-<para>
-This document describes how to write your own plugins. Note, that at the time of this writing, some of the concepts are not yet 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.
-</para>
-<para>
-For questions and comments, please write to the &rkward; development mailing list.
-</para>
-<para>
-<emphasis>You do not need to read this in order to use &rkward;.</emphasis> This document is about extending &rkward;. It is targeted at advanced users, or people willing to help improve &rkward;.
-</para>
-<para>
-Writing a standard plugin is basically a four-step process:
-<itemizedlist>
-<listitem><para><link linkend="pluginmap">Placing a new Action in the menu hierarchy</link></para></listitem>
-<listitem><para><link linkend="mainxml">Describing the looks and behavior of the plugin GUI</link></para></listitem>
-<listitem><para><link linkend="jstemplate">Defining, how R-code is to be generated from the settings, the user makes in the GUI</link></para></listitem>
-<listitem><para><link linkend="pluginhelp">Adding a help page to your plugin</link></para></listitem>
-</itemizedlist>
-Those will be dealt with in turn.
-</para>
-<para>
-Some advanced concepts may be used in those four steps, but are dealt with in separate chapters, to keep things simple:
-<itemizedlist>
-<listitem><para><link linkend="logic">GUI logic</link></para></listitem>
-<listitem><para><link linkend="embedding">Embedding Plugins into Plugins</link></para></listitem>
-<listitem><para><link linkend="plugin_series">Useful concepts for creating many series of similar plugins</link></para></listitem>
-</itemizedlist>
-</para>
-<para>
-Also, none of the chapters shows all options, but rather only the basic concepts. A complete <link linkend="reference">reference</link> of options is provided separately.
-</para>
+ <note>
+ <para>
+ Documentation as of &rkward; release 0.5.7.
+ </para>
+ </note>
+ <para>
+ This document describes how to write your own plugins. Note, that at the time of this writing, some of the concepts are not yet 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.
+ </para>
+ <para>
+ For questions and comments, please write to the &rkward; development mailing list.
+ </para>
+ <para>
+ <emphasis>You do not need to read this in order to use &rkward;.</emphasis> This document is about extending &rkward;. It is targeted at advanced users, or people willing to help improve &rkward;.
+ </para>
+ <para>
+ Writing a standard plugin is basically a four-step process:
+ <itemizedlist>
+ <listitem><para><link linkend="pluginmap">Placing a new Action in the menu hierarchy</link></para></listitem>
+ <listitem><para><link linkend="mainxml">Describing the looks and behavior of the plugin GUI</link></para></listitem>
+ <listitem><para><link linkend="jstemplate">Defining, how R-code is to be generated from the settings, the user makes in the GUI</link></para></listitem>
+ <listitem><para><link linkend="pluginhelp">Adding a help page to your plugin</link></para></listitem>
+ </itemizedlist>
+ Those will be dealt with in turn.
+ </para>
+ <para>
+ Some advanced concepts may be used in those four steps, but are dealt with in separate chapters, to keep things simple:
+ <itemizedlist>
+ <listitem><para><link linkend="logic">GUI logic</link></para></listitem>
+ <listitem><para><link linkend="embedding">Embedding Plugins into Plugins</link></para></listitem>
+ <listitem><para><link linkend="plugin_series">Useful concepts for creating many series of similar plugins</link></para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Also, none of the chapters shows all options, but rather only the basic concepts. A complete <link linkend="reference">reference</link> of options is provided separately.
+ </para>
</chapter>
<chapter id="whatareplugins">
<title>Preliminaries: What are plugins in &rkward;? How do they work?</title>
-<para>
-Of course the first question you might have is: What portions of &rkward; functionality is realized using plugins? Or: What can plugins do?
-</para>
-<para>
- One way to answer this is: Deselect all <literal role="extension">.pluginmap</literal> files under <menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure &rkward;</guimenuitem><guimenuitem>Plugins</guimenuitem></menuchoice>, and see what's missing. A slightly more helpful answer: Most actual statistics functions accessible via the GUI are realized using plugins. Also, you can create fairly flexible GUIs for all kinds of operations using plugins.
-</para>
-<para>
-The basic paradigm behind &rkward; plugins is the one we'll walk you through in this document: An XML file describes what the GUI looks like. An additional JavaScript file is used to generate &r; syntax from the GUI settings. That is, plugins do not really have to perform any statistical calculations. Rather plugins generate the &r; syntax needed to run those calculations. The &r; syntax is then sent to the &r; backend for evaluation, and typically a result is shown in the output window.
-</para>
-<para>
-Read on in the next chapters to see how this is done.
-</para>
+ <para>
+ Of course the first question you might have is: What portions of &rkward; functionality is realized using plugins? Or: What can plugins do?
+ </para>
+ <para>
+ One way to answer this is: Deselect all <literal role="extension">.pluginmap</literal> files under <menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure &rkward;</guimenuitem><guimenuitem>Plugins</guimenuitem></menuchoice>, and see what's missing. A slightly more helpful answer: Most actual statistics functions accessible via the GUI are realized using plugins. Also, you can create fairly flexible GUIs for all kinds of operations using plugins.
+ </para>
+ <para>
+ The basic paradigm behind &rkward; plugins is the one we'll walk you through in this document: An XML file describes what the GUI looks like. An additional JavaScript file is used to generate &r; syntax from the GUI settings. That is, plugins do not really have to perform any statistical calculations. Rather plugins generate the &r; syntax needed to run those calculations. The &r; syntax is then sent to the &r; backend for evaluation, and typically a result is shown in the output window.
+ </para>
+ <para>
+ Read on in the next chapters to see how this is done.
+ </para>
</chapter>
<chapter id="pluginmap">
<title>Creating menu entries</title>
-<para>
-When you create a new plugin, you need to tell &rkward; about it. So the first thing to do, is to write a <literal role="extension">.pluginmap</literal> file (or modify an existing one). The format of <literal role="extension">.pluginmap</literal> is XML. I'll walk you through an example (also of course, be sure you have &rkward; configured to load your pluginmap -- <menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure &rkward;</guimenuitem><guimenuitem>Plugins</guimenuitem></menuchoice>):
-</para>
-<tip><para>After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create most of &rkward;'s XML tags for you.</para></tip>
-<programlisting>
+ <para>
+ When you create a new plugin, you need to tell &rkward; about it. So the first thing to do, is to write a <literal role="extension">.pluginmap</literal> file (or modify an existing one). The format of <literal role="extension">.pluginmap</literal> is XML. I'll walk you through an example (also of course, be sure you have &rkward; configured to load your pluginmap -- <menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure &rkward;</guimenuitem><guimenuitem>Plugins</guimenuitem></menuchoice>):
+ </para>
+ <tip>
+ <para>
+ After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create most of &rkward;'s XML tags for you.
+ </para>
+ </tip>
+ <programlisting>
<!DOCTYPE rkpluginmap>
-</programlisting>
-<para>
-The doctype is not really interpreted, but set it to <quote>rkpluginmap</quote> anyway.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ The doctype is not really interpreted, but set it to <replaceable>"rkpluginmap"</replaceable> anyway.
+ </para>
+ <programlisting>
<document base_prefix="" namespace="rkward">
-</programlisting>
-<para>
- The <parameter>base_prefix</parameter>-attribute can be used, if all your plugins reside in a common directory. Basically, then, you can omit that directory from the filenames specified below. As you will see below, all plugins get a unique identifier. The <parameter>namespace</parameter> is a way to organize those ids, and make it less likely to create a duplicate identifier accidentally. Internally, basically the namespace and then a <quote>::</quote> gets prepended to all the identifiers you specify below. If unsure, leave these at <quote></quote> and <quote>rkward</quote>.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ The <parameter>base_prefix</parameter>-attribute can be used, if all your plugins reside in a common directory. Basically, then, you can omit that directory from the filenames specified below. As you will see below, all plugins get a unique identifier. The <parameter>namespace</parameter> is a way to organize those ids, and make it less likely to create a duplicate identifier accidentally. Internally, basically the namespace and then a <quote>::</quote> gets prepended to all the identifiers you specify below. If unsure, leave these at <replaceable>""</replaceable> and <replaceable>"rkward"</replaceable>.
+ </para>
+ <programlisting>
<components>
-</programlisting>
-<para>
-Components? Aren't we talking about plugins? Yes, but in the future, plugins will be no more than a special class of components. What we do here, then, is to register all components/plugins with &rkward;. Let's look at an example entry:
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Components? Aren't we talking about plugins? Yes, but in the future, plugins will be no more than a special class of components. What we do here, then, is to register all components/plugins with &rkward;. Let's look at an example entry:
+ </para>
+ <programlisting>
<component type="standard" id="independent_samples_t_test" file="means/ttests/independent_samples.xml" label="Independent Samples" />
-</programlisting>
-<para>
- First the <parameter>type</parameter>-attribute: Leave this to <quote>standard</quote> for now. Further types are not yet implemented. The <parameter>id</parameter> I've already hinted at. Each component has to be given a unique (in its namespace) identifier. Pick one that is easily recognizable. Avoid spaces and any special characters. Those are not banned, so far, but might have special meanings. With the <parameter>file</parameter> attribute, you specify where the <link linkend="mainxml">description of the actual plugin itself</link> is located. This is relative to the directory the <literal role="extension">.pluginmap</literal> file is in, and the <parameter>base_prefix</parameter> above. Finally, give the component a label. This label will be shown whereever the plugin is placed in the menu (or in the future perhaps in other places as well).
-</para>
-<para>
-Typically a <literal role="extension">.pluginmap</literal> file will contain several components, so here are a few more:
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ First the <parameter>type</parameter> attribute: Leave this to <replaceable>"standard"</replaceable> for now. Further types are not yet implemented. The <parameter>id</parameter> we've already hinted at. Each component has to be given a unique (in its namespace) identifier. Pick one that is easily recognizable. Avoid spaces and any special characters. Those are not banned, so far, but might have special meanings. With the <parameter>file</parameter> attribute, you specify where the <link linkend="mainxml">description of the actual plugin itself</link> is located. This is relative to the directory the <literal role="extension">.pluginmap</literal> file is in, and the <parameter>base_prefix</parameter> above. Finally, give the component a label. This label will be shown whereever the plugin is placed in the menu (or in the future perhaps in other places as well).
+ </para>
+ <para>
+ Typically a <literal role="extension">.pluginmap</literal> file will contain several components, so here are a few more:
+ </para>
+ <programlisting>
<component type="standard" id="unimplemented_test" file="means/unimplemented.xml" />
<component type="standard" id="fictional_t_test" file="means/ttests/fictional.xml" label="This is a fictional t-test" />
<component type="standard" id="descriptive" file="descriptive.xml" label="Descriptive Statistics" />
<component type="standard" id="corr_matrix" file="corr_matrix.xml" label="Correlation Matrix" />
<component type="standard" id="simple_anova" file="simple_anova.xml" label="Simple Anova" />
</components>
-</programlisting>
-<para>
-Ok, this was the first step. &rkward; now knows those plugins exist. But how to invoke them? They need to be placed in a menu hierarchy:
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Ok, this was the first step. &rkward; now knows those plugins exist. But how to invoke them? They need to be placed in a menu hierarchy:
+ </para>
+ <programlisting>
<hierarchy>
<menu id="analysis" label="Analysis" index="4">
-</programlisting>
-<para>
- Right below the <hierarchy> tag, you start describing, in which menu, your plugins should go. With the above line, you basically say, that your plugin should be in the <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu (not necessarily directly there, but in a submenu). The <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu is standard in &rkward;, so it does not actually have to be created from scratch. However, if it did not exist yet, using the <parameter>label</parameter> attribute you'd give it its name. The <parameter>index</parameter> attribute says, that the menu (if newly created) should be placed at the fourth position in the menubar.
- Finally, the <parameter>id</parameter> once again identifies this menu. This is needed, so several <literal role="extension">.pluginmap</literal> files can place their plugins in the same menus. They do this by looking for a menu with the given <parameter>id</parameter>. If the id does not yet exist, a new menu will be created. Otherwise the entries will be added to the existing menu.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Right below the <command><hierarchy></command> tag, you start describing, in which menu, your plugins should go. With the above line, you basically say, that your plugin should be in the <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu (not necessarily directly there, but in a submenu). The <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu is standard in &rkward;, so it does not actually have to be created from scratch. However, if it did not exist yet, using the <parameter>label</parameter> attribute you'd give it its name. The <parameter>index</parameter> attribute says, that the menu (if newly created) should be placed at the fourth position in the menubar.
+ Finally, the <parameter>id</parameter> once again identifies this menu. This is needed, so several <literal role="extension">.pluginmap</literal> files can place their plugins in the same menus. They do this by looking for a menu with the given <parameter>id</parameter>. If the ID does not yet exist, a new menu will be created. Otherwise the entries will be added to the existing menu.
+ </para>
+ <programlisting>
<menu id="means" label="Means" index="1">
-</programlisting>
-<para>
-Basically the same thing here: Now we define a submenu to the <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu. It is to be called <menuchoice><guimenuitem>Means</guimenuitem></menuchoice>.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Basically the same thing here: Now we define a submenu to the <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu. It is to be called <menuchoice><guimenuitem>Means</guimenuitem></menuchoice>.
+ </para>
+ <programlisting>
<menu id="ttests" label="T-Tests">
-</programlisting>
-<para>
- And a final level in the menu-hierarchy: A sub-menu of the sub-menu <menuchoice><guimenuitem>Means</guimenuitem></menuchoice>. Note, that if you omit the <parameter>index</parameter> parameter, the new entry will be placed below any already existing ones.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ And a final level in the menu-hierarchy: A sub-menu of the sub-menu <menuchoice><guimenuitem>Means</guimenuitem></menuchoice>. Note, that if you omit the <parameter>index</parameter> parameter, the new entry will be placed below any already existing ones.
+ </para>
+ <programlisting>
<entry component="independent_samples_t_test" />
-</programlisting>
-<para>
- Now, finally, this is the menu, we want to place the plugin in. The <entry>-tag signals, this actually is the real thing, instead of another submenu. The <parameter>component</parameter> attribute refers to the <parameter>id</parameter> you gave the plugin/component above.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Now, finally, this is the menu, we want to place the plugin in. The <command><entry></command> tag signals, this actually is the real thing, instead of another submenu. The <parameter>component</parameter> attribute refers to the <parameter>id</parameter> you gave the plugin/component above.
+ </para>
+ <programlisting>
<entry component="fictional_t_test" />
</menu>
<entry component="fictional_t_test" />
</menu>
<menu id="frequency" label="Frequency" index="2"/>
-</programlisting>
-<para>
-In case you have lost track: This is another submenu to the <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu. See the screenshot below. We'll skip some of what's not visible, marked with [...].
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ In case you have lost track: This is another submenu to the <menuchoice><guimenu>Analysis</guimenu></menuchoice> menu. See the screenshot below. We'll skip some of what's not visible, marked with [...].
+ </para>
+ <programlisting>
[...]
</menu>
<entry component="corr_matrix" index="4"/>
<entry component="descriptive" index="3"/>
<entry component="simple_anova" index="5"/>
</menu>
-</programlisting>
-<para>
-These are the final entries visible in the screenshots below. Note, that you don't need to define the entries in the order they should have in the menu. Use the <parameter>index</parameter> attribute instead.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ These are the final entries visible in the screenshots below. Note, that you don't need to define the entries in the order they should have in the menu. Use the <parameter>index</parameter> attribute instead.
+ </para>
+ <programlisting>
<menu id="plots" label="Plots" index="5">
[...]
</menu>
-</programlisting>
-<para>
-Of course you can also place your plugins in menus other than <menuchoice><guimenu>Analysis</guimenu></menuchoice>.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Of course you can also place your plugins in menus other than <menuchoice><guimenu>Analysis</guimenu></menuchoice>.
+ </para>
+ <programlisting>
<menu id="file" label="File" index="0">
[...]
</menu>
-</programlisting>
-<para>
- Even in standard-menus such as <menuchoice><guimenu>File</guimenu></menuchoice>. All you need is the correct <parameter>id</parameter>.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Even in standard-menus such as <menuchoice><guimenu>File</guimenu></menuchoice>. All you need is the correct <parameter>id</parameter>.
+ </para>
+ <programlisting>
</hierarchy>
</document>
-</programlisting>
-<para>
-That's how to do it. And this screenshot shows the result:
-</para>
-<screenshot>
-<screeninfo>Menu hierarchy created by the code shown above</screeninfo>
- <mediaobject>
- <imageobject>
- <imagedata fileref="menu_hierarchy_example.png" format="PNG"/>
- </imageobject>
- <textobject>
- <phrase>Menu hierarchy created by the code shown above</phrase>
- </textobject>
- </mediaobject>
-</screenshot>
-<para>
-Confused? The easiest way to get started is probably taking some of the existing <literal role="extension">.pluginmap</literal> files shipped with the distribution, and modifying them to your needs. Also, if you need help, don't hesitate to write to the development mailing list.
-</para>
+ </programlisting>
+ <para>
+ That's how to do it. And this screenshot shows the result:
+ </para>
+ <screenshot>
+ <screeninfo>Menu hierarchy created by the code shown above</screeninfo>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="menu_hierarchy_example.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>Menu hierarchy created by the code shown above</phrase>
+ </textobject>
+ </mediaobject>
+ </screenshot>
+ <para>
+ Confused? The easiest way to get started is probably taking some of the existing <literal role="extension">.pluginmap</literal> files shipped with the distribution, and modifying them to your needs. Also, if you need help, don't hesitate to write to the development mailing list.
+ </para>
</chapter>
<chapter id="mainxml">
<title>Defining the GUI</title>
-<para>
-In the <link linkend="pluginmap">previous chapter</link> you've seen how to register a plugin with &rkward;. The most important ingredient was specifying the path to an XML file with a description of what the plugin actually looks like. In this chapter you'll learn how to create this XML file.
-</para>
-<tip><para>After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create most of &rkward;'s XML tags for you.</para></tip>
-<para>
-Once again we'll walk you through an example. The example is a (slightly simplified) version of the independent samples t-Test.
-</para>
-<programlisting>
+<sect1 id="sect_defining_the_GUI"><title>Defining a dialog</title>
+ <para>
+ In the <link linkend="pluginmap">previous chapter</link> you've seen how to register a plugin with &rkward;. The most important ingredient was specifying the path to an XML file with a description of what the plugin actually looks like. In this chapter you'll learn how to create this XML file.
+ </para>
+ <tip>
+ <para>
+ After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create most of &rkward;'s XML tags for you.
+ </para>
+ </tip>
+ <para>
+ Once again we'll walk you through an example. The example is a (slightly simplified) version of the independent samples t-Test.
+ </para>
+ <programlisting>
<!DOCTYPE rkplugin>
-</programlisting>
-<para>
-The doctype is not really interpreted, yet. Set it to rkplugin, anyway.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ The doctype is not really interpreted, yet. Set it to <replaceable>rkplugin</replaceable>, anyway.
+ </para>
+ <programlisting>
<document>
<code file="t_test.js"/>
-</programlisting>
-<para>
-All plugins generate some code. Currently the only way to do so is using JS, as detailed in <link linkend="jstemplate">the next chapter</link>. This defines, where to look for the JS code. The filename is relative to the directory the plugin XML is in.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ All plugins generate some code. Currently the only way to do so is using JS, as detailed in <link linkend="jstemplate">the next chapter</link>. This defines, where to look for the JS code. The filename is relative to the directory the plugin XML is in.
+ </para>
+ <programlisting>
<help file="t_test.rkh"/>
-</programlisting>
-<para>
-It is usually a good idea to also provide a help page for your plugin. The filename of that help page is given, here, relative to the directory, the plugin XML is in. Writing help pages is documented <link linkend="pluginhelp">here</link>. If you do not provide a help file, omit this line.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ It is usually a good idea to also provide a help page for your plugin. The filename of that help page is given, here, relative to the directory, the plugin XML is in. Writing help pages is documented <link linkend="pluginhelp">here</link>. If you do not provide a help file, omit this line.
+ </para>
+ <programlisting>
<dialog label="Independent Samples t-Test">
-</programlisting>
-<para>
- As you know, plugins may have either a dialog or a wizard interface or both. Here we start definining a dialog interface. the <parameter>label</parameter> attribute specifies the caption of the dialog.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ As you know, plugins may have either a dialog or a wizard interface or both. Here we start definining a dialog interface. the <parameter>label</parameter> attribute specifies the caption of the dialog.
+ </para>
+ <programlisting>
<tabbook>
<tab label="Basic settings">
-</programlisting>
-<para>
-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 <parameter>label</parameter> attribute in the <tab> element allows you to specify a caption for that page of the tabbook.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ GUI elements can be organized using a tabbook. Here we define a tabbook as the first element in the dialog. Use <command><tabbook></command>[...]<command></tabbook></command> to define the tabbook and then for each page in the tabbook use <command><tab></command>[...]<command></tab></command>. The <parameter>label</parameter> attribute in the <command><tab></command> element allows you to specify a caption for that page of the tabbook.
+ </para>
+ <programlisting>
<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). The <parameter>id</parameter> 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>
+ </programlisting>
+ <para>
+ The <command><row></command> and <command><column></command> 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 <parameter>id</parameter> 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"/>
-</programlisting>
-<para>
-Using this simple tag you create a list from which the user can select variables. You have to specify an id for this element, so &rkward; knows how to find it. Note that you may NOT use a dot (.) in the <parameter>id</parameter> string.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Using this simple tag you create a list from which the user can select variables. You have to specify an <parameter>id</parameter> for this element, so &rkward; knows how to find it.
+ </para>
+ <warning>
+ <remark>
+ You may NOT use a dot (.) in the <parameter>id</parameter> string.
+ </remark>
+ </warning>
+ <programlisting>
<column>
-</programlisting>
-<para>
-Next, we nest a <column> inside the row. I.e. the following elements will be place above each other (top-to-bottom), and all will be to the right of the <varselector>.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Next, we nest a <command><column></command> inside the row. I.e. the following elements will be place above each other (top-to-bottom), and all will be to the right of the <command><varselector></command>.
+ </para>
+ <programlisting>
<varslot types="number" id="x" source="vars" required="true" label="compare"/>
<varslot types="number" id="y" source="vars" required="true" label="against"/>
-</programlisting>
-<para>
- These elements are the counterpart to the <varselector>. They represent <quote>slots</quote> into which the user can put variables. You will note that the <parameter>source</parameter> is set to the same value as the <parameter>id</parameter> of the <varselector>. This means, the <varslot>s will each take their variables from the varselector. The <varslot>s also have to be given an <parameter>id</parameter>. They may have a label, and they may be set to <quote>required</quote>. This means that the <guibutton>Submit</guibutton> button will not be enabled until the <varslot> holds a valid value. Finally the <parameter>type</parameter> attribute is not interpreted, yet, but it will be used to take care that only the correct types of variables will be allowed in the <varslot>.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ These elements are the counterpart to the <command><varselector></command>. They represent <quote>slots</quote> into which the user can put variables. You will note that the <parameter>source</parameter> is set to the same value as the <parameter>id</parameter> of the <command><varselector></command>. This means, the <command><varslot></command>s will each take their variables from the varselector. The <command><varslot></command>s also have to be given an <parameter>id</parameter>. They may have a <parameter>label</parameter>, and they may be set to <parameter>required</parameter>. This means that the <guibutton>Submit</guibutton> button will not be enabled until the <command><varslot></command> holds a valid value. Finally the <parameter>type</parameter> attribute is not interpreted yet, but it will be used to take care that only the correct types of variables will be allowed in the <command><varslot></command>.
+ </para>
+ <programlisting>
<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>
-</programlisting>
-<para>
-Here, you define a group of <radio>-exclusive buttons. The group has a <parameter>label</parameter> and an <parameter>id</parameter>. Each <option> (button) has a label and is assigned a value. This is the value the <radio>-element will return when the option is selected.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Here, you define a group of <command><radio></command> exclusive buttons. The group has a <parameter>label</parameter> and an <parameter>id</parameter>. Each <command><option></command> (button) has a <parameter>label</parameter> and is assigned a <parameter>value</parameter>. This is the value the <command><radio></command> element will return when the option is selected.
+ </para>
+ <programlisting>
</column>
</row>
</tab>
-</programlisting>
-<para>
-Each tag has to be closed. We've put all the elements we wanted (the two <varslots> and the <radio>) in the <column>. We put all elements we wanted (the <varselector> and the <column> with those elements) in the <row>. And we've put all the elements we wanted into the first page in the <tabbook>. We're not yet done defining the <tabbook> (more pages to come) and of course there's more to come in the <dialog>, too. But this screenshot is basically what we've done so far:
-</para>
-<screenshot>
-<screeninfo>T test plugin</screeninfo>
- <mediaobject>
- <imageobject>
- <imagedata fileref="t_test_plugin_example.png" format="PNG"/>
- </imageobject>
- <textobject>
- <phrase>T test plugin</phrase>
- </textobject>
- </mediaobject>
-</screenshot>
-<para>
- Note that we have not specified the <guibutton>Submit</guibutton>, <guibutton>Close</guibutton>, etc. buttons or the code-view. Those elements get generated automatically. But of course we still have to define the second page of the <tabbook>:
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Each tag has to be closed. We've put all the elements we wanted (the two <command><varslots></command> and the <command><radio></command>) in the <command><column></command>. We put all elements we wanted (the <command><varselector></command> and the <command><column></command> with those elements) in the <command><row></command>. And we've put all the elements we wanted into the first page in the <command><tabbook></command>. We're not yet done defining the <command><tabbook></command> (more pages to come), and of course there's more to come in the <command><dialog></command>, too. But this screenshot is basically what we've done so far:
+ </para>
+ <screenshot>
+ <screeninfo>T test plugin</screeninfo>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="t_test_plugin_example.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>T test plugin</phrase>
+ </textobject>
+ </mediaobject>
+ </screenshot>
+ <para>
+ Note that we have not specified the <guibutton>Submit</guibutton>, <guibutton>Close</guibutton>, etc. buttons or the code view. Those elements get generated automatically. But of course we still have to define the second page of the <command><tabbook></command>:
+ </para>
+ <programlisting>
<tab label="Options">
<checkbox id="varequal" label="assume equal variances" value=", var.equal=TRUE"/>
-</programlisting>
-<para>
-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 <parameter>label</parameter> and a <parameter>value</parameter>. The <parameter>value</parameter> is what gets returned, if the checkbox is checked. Of course the checkbox also needs an <parameter>id</parameter>.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ By default elements will be placed top-to-bottom like in a <command><column></command>. Since that is what we want here, we don't have to explicitly state a <command><row></command> or <command><column></command> layout. The first element we define is a checkbox. Just like the <command><radio></command><command><option></command>s, the checkbox has a <parameter>label</parameter> and a <parameter>value</parameter>. The <parameter>value</parameter> is what gets returned, if the checkbox is checked. Of course the checkbox also needs an <parameter>id</parameter>.
+ </para>
+ <programlisting>
<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 <parameter>id</parameter>, we still define one here, as we'll refer to it later, when defining an additional wizard interface.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ Here's yet another layout element: In order to signal that the two elements below belong together, we draw a <command><frame></command> (box). That frame may have a <parameter>label</parameter> (caption). Since the frame is just a passive layout element, it does not need an <parameter>id</parameter>, 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"/>
<spinbox type="real" id="conflevel" label="confidence level" min="0" max="1" initial="0.95"/>
</frame>
-</programlisting>
-<para>
- Inside the <frame> we place another <checkbox> (using <parameter>checked</parameter>=<replaceable>"true"</replaceable>, we signal that checkbox should be checked by default), and a <spinbox>. The spinbox allows the user to select a value between <replaceable>"min"</replaceable> and <replaceable>"max"</replaceable> with the default/initial value <replaceable>"0.95"</replaceable>. Setting the <parameter>type</parameter> to <replaceable>"real"</replaceable> signals that real numbers are accepted as opposed to <parameter>type</parameter>=<replaceable>"integer"</replaceable> which would accept integers only.
-</para>
-<note><para>
-It is also possible, and often preferrable, to make the <frame> itself checkable, instead of adding a <checkbox> inside. See the reference for details. This is not done, here, for illustrational purposes.
-</para></note>
-<programlisting>
+ </programlisting>
+ <para>
+ Inside the <command><frame></command> we place another <command><checkbox></command> (using <parameter>checked=</parameter><replaceable>"true"</replaceable>, we signal that checkbox should be checked by default), and a <command><spinbox></command>. The spinbox allows the user to select a value between <replaceable>"min"</replaceable> and <replaceable>"max"</replaceable> with the default/initial value <replaceable>"0.95"</replaceable>. Setting the <parameter>type</parameter> to <replaceable>"real"</replaceable> signals that real numbers are accepted as opposed to <parameter>type=</parameter><replaceable>"integer"</replaceable> which would accept integers only.
+ </para>
+ <note><para>
+ It is also possible, and often preferrable, to make the <command><frame></command> itself checkable, instead of adding a <command><checkbox></command> inside. See the reference for details. This is not done here, for illustrational purposes.
+ </para></note>
+ <programlisting>
</tab>
</tabbook>
</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.
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ That's all for the second page of the <command><tabbook></command>, all pages in the <command><tabbook></command> and all elements in the<command> <dialog></command>. We're finished defining what the dialog looks like.
+ </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="jstemplate">next chapter</link>. First, however, we'll look into adding a wizard interface, and some general considerations.
-</para>
+ </programlisting>
+ <para>
+ Finally we close the <command><document></command> 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? We'll deal with that in the <link linkend="jstemplate">next chapter</link>. First, however, we'll look into adding a wizard interface, and some general considerations.
+ </para>
+</sect1>
<sect1 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:
+ Actually we don't have to define an additional <command><wizard></command> interface, but here's how that would be done. To add a wizard interface, you'll add a <command><wizard></command> tag at the same level as the <command><dialog></command> tag:
</para>
<programlisting>
- <wizard label="Independent Samples T-Test">
+ <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 <parameter>id</parameter> 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 <quote>hypothesis</quote> <radio>-control. All of this is copied 1:1 and inserted right at the <copy> element.
+ Some of this is pretty self explanatory: We add a <command><wizard></command> 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 <command><page></command>, and put an explanatory <command><text></command> note in there. Then we use a <command><copy></command> tag. What this does, is really it saves us having to define yet again, what we already wrote for the <command><dialog></command>: The copy tag looks for another tag with the same <parameter>id</parameter> earlier in the .xml. This happens to be defined in the <command><dialog></command> section, and is a <command><row></command> in which there are the <command><varselector></command>, <command><varslots></command> and the <quote>hypothesis</quote> <command><radio></command> control. All of this is copied 1:1 and inserted right at the <command><copy></command> element.
</para>
<para>
- Now to the second page:
+ Now to the second page:
</para>
<programlisting>
<page id="secondpage">
@@ -421,29 +437,29 @@
</wizard>
</programlisting>
<para>
- Much of the same thing here. We add some texts, and in between that <copy> further sections from the dialog interface.
+ Much of the same thing here. We add some texts, and in between that <command><copy></command> 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 <parameter>id</parameter> 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).
+ You may of course make the wizard interface look very different to the plain dialog, and not use the <command><copy></command> tag at all. Be sure, however, to assign corresponding elements the same <parameter>id</parameter> 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>
</sect1>
<sect1 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.
+ 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>
<sect2 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 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:
+ The three elements <command><radio></command>, <command><checkbox></command>, <command><dropdown></command>, all serve a similar function: To select one out of 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 <quote>adjust results</quote> and <quote>do not adjust results</quote>, or between <quote>remove missing values</quote> and <quote>keep missing values</quote>. 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: <quote>Method of calculation: 'pearson'/'spearman'</quote>. Here, more methods might be thinkable, and they don't really form a pair of opposites.
+ If you find yourself creating a <command><radio></command> or <command><dropdown></command> with only two options, ask yourself, whether the question is essentially a yes / no type of question. E.g. a choice between <quote>adjust results</quote> and <quote>do not adjust results</quote>, or between <quote>remove missing values</quote> and <quote>keep missing values</quote>. In this case a <command><checkbox></command> 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 <command><radio></command> over a <command><checkbox></command>, when there are only two options. An example of that might be: <quote>Method of calculation: 'pearson'/'spearman'</quote>. 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.
+ Chosing between a <command><radio></command> and a <command><dropdown></command> is mostly a question of space. The <command><dropdown></command> has the advantage of using little space, even if there are a lot of options to chose from. On the other hand, a <command><radio></command> 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 <command><dropdown></command> is preferrable. If there are five or less options, a <command><radio></command> is the better choice.
</para>
</sect2>
</sect1>
@@ -451,107 +467,117 @@
<chapter id="jstemplate">
<title>Generating R code from GUI settings</title>
-<para>
- Now we have a GUI defined, but we still need to generate some &r; code from that. For that, we need another text file, <filename>code.js</filename>, located in the same directory as the <link linkend="mainxml"><filename>description.xml</filename></link>. You may or may not be familiar with JavaScript (or, to be technically precise: ECMA-script). Documentation on JS can be found in abundance, both in printed form, and on the internet (e.g.: <ulink url="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide">https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide</ulink>). But for most purposes you will not need to know much about JS at all, as we'll only use some very basic features.
-</para>
-<tip><para>After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create JavaScript code commonly used in &rkward;. For instance, it can autodetect variables used in a plugin XML file and create basic JavaScript code from that for you to start with.</para></tip>
-<para>
-For the independent samples t-test, the <filename>code.js</filename> file looks as follows (with comments in between):
-</para>
-<programlisting>
+<sect1 id="sect_generating_R_code"><title>Using JavaScript in RKWard plugins</title>
+ <para>
+ Now we have a GUI defined, but we still need to generate some &r; code from that. For that, we need another text file, <filename>code.js</filename>, located in the same directory as the <link linkend="mainxml"><filename>description.xml</filename></link>. You may or may not be familiar with JavaScript (or, to be technically precise: ECMA-script). Documentation on JS can be found in abundance, both in printed form, and on the internet (e.g.: <ulink url="https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide">https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide</ulink>). But for most purposes you will not need to know much about JS at all, as we'll only use some very basic features.
+ </para>
+ <tip>
+ <para>
+ After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create JavaScript code commonly used in &rkward;. It can also autodetect variables used in a plugin XML file and create basic JavaScript code from that for you to start with.
+ </para>
+ </tip>
+ <para>
+ For the independent samples t-test, the <filename>code.js</filename> file looks as follows (with comments in between):
+ </para>
+ <sect2 id="sect_JS_preprocess"><title>preprocess()</title>
+ <programlisting>
function preprocess () {
}
-</programlisting>
-<para>
-The JS file is organized into three separate functions: <function>preprocess()</function>, <function>calculate()</function>, and <function>printout()</function>. This is because not all code is needed at all stages. Currently the preprocess-function is not really used in many places (typically you will omit it altogether).
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ The JS file is organized into three separate functions: <function>preprocess()</function>, <function>calculate()</function>, and <function>printout()</function>. This is because not all code is needed at all stages. Currently the preprocess-function is not really used in many places (typically you will omit it altogether).
+ </para>
+ </sect2>
+ <sect2 id="sect_JS_calculate"><title>calculate()</title>
+ <programlisting>
function calculate () {
echo ('res <- t.test (x=' + getValue ("x") + ', y=' + getValue ("y") + ', hypothesis="' + getValue ("hypothesis") + '"' + getValue ("varequal"));
var conflevel = getValue ("conflevel");
if (conflevel != "0.95") echo (', conf.level=' + conflevel);
echo (')\n');
}
-</programlisting>
-<para>
-This function generates the actual R-syntax to be run from the GUI-settings. Let's look at this in detail:
- The code to be used is generated using <function>echo()</function> statement. Looking at the <function>echo()</function> statement step by step, the first part of it is
-</para>
-<screen>
+ </programlisting>
+ <para>
+ This function generates the actual R syntax to be run from the GUI settings. Let's look at this in detail: The code to be used is generated using <function>echo()</function> statement. Looking at the <function>echo()</function> statement step by step, the first part of it is
+ </para>
+ <screen>
res <- t.test (
-</screen>
-<para>
- as plain text. Next we need to fill in the value, the user selected as the first variable. We fetch this using <function>getValue ("x")</function>, and append it to the string to be <quote>echoed</quote>. This prints out the value of the GUI-element with id <quote>x</quote>: our first <varslot>. Next, we append a ', ', and do the same to fetch the value of the element <quote>y</quote> - the second <varslot>. For the hypothesis (the <radio>-group), and the equal variances-<checkbox>, the procedure is very similar.
-</para>
-<para>
-Note that instead of concatenating the output-snippets with <quote>+</quote>, you can also use several <function>echo()</function>-statments. Everything is printed on a single line. To produce a line break in the generated code, insert a <quote>\n</quote> in the echoed string. In theory, you can even produce many lines with a single echo-statement, but please keep it to one line (or less) of generated code per <function>echo()</function>.
-</para>
-<para>
-It gets a little more tricky for the confidence level. For reasons of aestethics, we don't want to explicitly specify the confidence level to use, if it corresponds to the default value. Hence, instead of printing the value unconditionally, we first fetch into a variable. Then we check, whether that variable differs from "0.95" and if so print out an additional argument.
-Finally, we echo a closing bracket and a line break: <quote>)\n</quote>. That's all for the calculate-function.
-</para>
-<programlisting>
+ </screen>
+ <para>
+ as plain text. Next we need to fill in the value, the user selected as the first variable. We fetch this using <function>getValue ("x")</function>, and append it to the string to be <quote>echoed</quote>. This prints out the value of the GUI-element with <parameter>id=</parameter><replaceable>"x"</replaceable>: our first <command><checkbox></command>. Next, we append a ', ', and do the same to fetch the value of the element <replaceable>"y"</replaceable> - the second <command><checkbox></command>. For the hypothesis (the <command><radio></command> group), and the equal variances <command><checkbox></command>, the procedure is very similar.
+ </para>
+ <para>
+ Note that instead of concatenating the output snippets with <quote>+</quote>, you can also use several <function>echo()</function> statments. Everything is printed on a single line. To produce a line break in the generated code, insert a <replaceable>"\n"</replaceable> in the echoed string. In theory, you can even produce many lines with a single echo-statement, but please keep it to one line (or less) of generated code per <function>echo()</function>.
+ </para>
+ <para>
+ It gets a little more tricky for the confidence level. For reasons of aestethics, we don't want to explicitly specify the confidence level to use, if it corresponds to the default value. Hence, instead of printing the value unconditionally, we first fetch into a variable. Then we check, whether that variable differs from <replaceable>"0.95"</replaceable> and if so print out an additional argument. Finally, we echo a closing bracket and a line break: <replaceable>")\n"</replaceable>. That's all for the calculate function.
+ </para>
+ </sect2>
+ <sect2 id="sect_JS_printout"><title>printout()</title>
+ <programlisting>
function printout () {
echo ('rk.header ("Independent samples t test")\n');
echo ('rk.print (res)\n');
}
-</programlisting>
-<para>
-And this was all there is to the printout function in most cases. <function>rk.header ()</function> prints a standard headline for the results. You can also add some more information to this, if you like, e.g.:
-</para>
-<programlisting>
+ </programlisting>
+ <para>
+ And this was all there is to the printout function in most cases. <function>rk.header()</function> 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 () {
makeHeaderCode ("Independent samples t test", new Array ("Assume equal variances", getValue ("varequal"), "Confidence level", getValue ("conflevel")))
echo ('rk.print (res)\n');
}
-</programlisting>
-<para>
- <function>rk.print()</function> utilizes the R2HTML package to provide HTML formatted output. Another helpful function is <function>rk.results()</function>, which can also output different kinds of result tables. If in doubt, however, just use <function>rk.print()</function>, and be done with. <function>makeHeaderCode()</function> is a JS level helper function to create a call to <function>rk.header()</function> (just take a look at the generated code). In some cases you may want to call <function>echo ('rk.header (...)')</function> directly to print a header for your output.
-</para>
-<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 <function>rk.cat.output ()</function>. 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 <function>rk.header ()</function>, <function>rk.print ()</function>, <function>rk.results ()</function>, and - if needed - <function>rk.print.literal()</function>. If those don't seem to satisfy your formatting needs, contact us on the mailing list for help.
-</para>
-<para>
-Congratulations! You created your first plugin. Read on in the next chapters for more advanced concepts.
-</para>
+ </programlisting>
+ <para>
+ <function>rk.print()</function> utilizes the R2HTML package to provide HTML formatted output. Another helpful function is <function>rk.results()</function>, which can also output different kinds of result tables. If in doubt, however, just use <function>rk.print()</function>, and be done with. <function>makeHeaderCode()</function> is a JS level helper function to create a call to <function>rk.header()</function> (just take a look at the generated code). In some cases you may want to call <function>echo ('rk.header (...)')</function> directly to print a header for your output.
+ </para>
+ <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 <function>rk.cat.output()</function>. 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 <function>rk.header()</function>, <function>rk.print()</function>, <function>rk.results()</function>, and -- if needed -- <function>rk.print.literal()</function>. If those don't seem to satisfy your formatting needs, contact us on the mailing list for help.
+ </para>
+ <para>
+ Congratulations! You created your first plugin. Read on in the next chapters for more advanced concepts.
+ </para>
+ </sect2>
+</sect1>
<sect1 id="jsconventions">
<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 JS. 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>
+ <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 JS. 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>
-<sect2 id="policylocal">
-<title>Understanding the <function>local()</function> 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. 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 <function>local()</function> environment (see &r; help page on function <function>local()</function>). This means, all variables you create are temporary and will not be saved permanently.
-</para>
-<para>
-If the user explicitely asks for a variable to be saved, you will need to assign to that object using <quote>.GlobalEnv$objectname <- value</quote>. In general, do not use the <quote><<-</quote> operator. It will not necessarily assign in .GlobalEnv.
-</para>
-<para>
-One important pitfall is using <function>eval()</function>. Here, you need to note that eval will by default use the current environment for evaluation, i.e. the local one. This will work well most of the times, but but not always. Thus, if you need to use <function>eval()</function>, you will probably want to specify the <parameter>envir</parameter> parameter: <function>eval(..., envir=globalenv()</function>).
-</para>
-</sect2>
+ <sect2 id="policylocal">
+ <title>Understanding the <function>local()</function> 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. 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 <function>local()</function> environment (see &r; help page on function <function>local()</function>). This means, all variables you create are temporary and will not be saved permanently.
+ </para>
+ <para>
+ If the user explicitely asks for a variable to be saved, you will need to assign to that object using <quote>.GlobalEnv$objectname <- value</quote>. In general, do not use the <quote><<-</quote> operator. It will not necessarily assign in .GlobalEnv.
+ </para>
+ <para>
+ One important pitfall is using <function>eval()</function>. Here, you need to note that eval will by default use the current environment for evaluation, i.e. the local one. This will work well most of the times, but but not always. Thus, if you need to use <function>eval()</function>, you will probably want to specify the <parameter>envir</parameter> parameter: <function>eval(..., envir=globalenv()</function>).
+ </para>
+ </sect2>
-<sect2 id="policyformatting">
-<title>Code formatting</title>
-<para>
-The most important thing is for your generated &r; code to work. But please also keep an eye on formatting. Some considerations:
-</para>
-<para>
-Normal top-level &r; statements should be left aligned.
-</para>
-<para>
-Statements in a lower block should be indented with one tab (see example below).
-</para>
-<para>
-If you do very complex calculations, add a comment here and there, esp. to mark up logical sections.
-</para>
-<para>
-For example, generated code might look like this. The same code without indentation or comments would be pretty hard to read, despite its modest complexity:
-</para>
-<programlisting>
+ <sect2 id="policyformatting">
+ <title>Code formatting</title>
+ <para>
+ The most important thing is for your generated &r; code to work. But please also keep an eye on formatting. Some considerations:
+ </para>
+ <para>
+ Normal top-level &r; statements should be left aligned.
+ </para>
+ <para>
+ Statements in a lower block should be indented with one tab (see example below).
+ </para>
+ <para>
+ If you do very complex calculations, add a comment here and there, esp. to mark up logical sections.
+ </para>
+ <para>
+ For example, generated code might look like this. The same code without indentation or comments would be pretty hard to read, despite its modest complexity:
+ </para>
+ <programlisting>
# first determine the wobble and rotation
my.wobble <- wobble (x, y)
my.rotation <- wobble.rotation (my.wobble, z)
@@ -564,15 +590,15 @@
method <- "bar"
result <- boggle.bar (my.wobble, my.rotation)
}
-</programlisting>
-</sect2>
+ </programlisting>
+ </sect2>
-<sect2 id="policysimplicity">
-<title>Dealing with complex options</title>
-<para>
-Many plugins can do more than one thing. For instance, the <quote>Descriptive Statistics</quote> 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 JS):
-</para>
-<programlisting>
+ <sect2 id="policysimplicity">
+ <title>Dealing with complex options</title>
+ <para>
+ Many plugins can do more than one thing. For instance, the <quote>Descriptive Statistics</quote> 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 JS):
+ </para>
+ <programlisting>
function calculate () {
echo ('x <- <' + getValue ("x") + ')\n');
echo ('results <- list ()\n');
@@ -582,20 +608,20 @@
if (getValue ("dosd")) echo ("results$'Standard deviation' <- sd (x)\n");
//...
}
-</programlisting>
-</sect2>
+ </programlisting>
+ </sect2>
</sect1>
<sect1 id="jstips">
<title>Tips and tricks</title>
-<para>
-Here are a few assorted tricks which may make writing plugins less tedious:
-</para>
-<para>
-If you need the value of a GUI setting at several places in you plugin's code, consider assigning it to a variable in JS, and using that instead of fetching it again and again with getValue. This is faster, more readable, and less typing all at the same time:
-</para>
-<programlisting>
+ <para>
+ Here are a few assorted tricks which may make writing plugins less tedious:
+ </para>
+ <para>
+ If you need the value of a GUI setting at several places in you plugin's code, consider assigning it to a variable in JS, and using that instead of fetching it again and again with getValue. This is faster, more readable, and less typing all at the same time:
+ </para>
+ <programlisting>
function calculate () {
var narm = ""; // na.rm=FALSE is the default in all functions below
if (getValue ("remove_nas") == "1") {
@@ -607,133 +633,137 @@
echo ("results$foobar <- foobar (x" + narm "\n");
// ...
}
-</programlisting>
+ </programlisting>
</sect1>
-
</chapter>
<chapter id="pluginhelp">
<title>Writing a help page</title>
<para>
- When your plugin basically works, the time has come to provide a help page. While typically you will not want to explain all the underlying concepts in depth, you may want to add some more explanation for some of the options, and link to related plugins and &r; functions.
+ When your plugin basically works, the time has come to provide a help page. While typically you will not want to explain all the underlying concepts in depth, you may want to add some more explanation for some of the options, and link to related plugins and &r; functions.
</para>
- <tip><para>After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create most of &rkward;'s XML tags for you. It's also capable of creating basic help file skeletons from existing plugin XML files for you to start with.</para></tip>
+ <tip>
+ <para>
+ After reading this chapter, have a look at the <link linkend="rkwarddev"><application>rkwarddev</application> package</link> as well. It provides some &r; functions to create most of &rkward;'s XML tags for you. It's also capable of creating basic help file skeletons from existing plugin XML files for you to start with.
+ </para>
+ </tip>
<para>
- You may recall putting this inside your plugin-xml (if you haven't put this in, do so now):
+ You may recall putting this inside your plugin XML (if you haven't put this in, do so now):
</para>
<programlisting>
- <document>
- [...]
- <help file="filename.rkh" />
- [...]
- </document>
+<document>
+ [...]
+ <help file="filename.rkh" />
+ [...]
+</document>
</programlisting>
<para>
- Where, obviously, you'd replace <filename>filename</filename> with a more appropriate name. Now it's time to create this <literal role="extension">.rkh</literal> file. Here is a self-descriptive example:
+ Where, obviously, you'd replace <filename>filename</filename> with a more appropriate name. Now it's time to create this <literal role="extension">.rkh</literal> file. Here is a self-descriptive example:
</para>
<programlisting>
- <!DOCTYPE rkhelp>
- <document>
- <summary>
- In this section, you'll put some short, very basic information about what the plugin does.
- This section will always show up on the very top of the help page.
- </summary>
-
- <usage>
- The usage section may contain a little more practical information. It does not explain all
- the settings in detail (that's done in the "settings" section), however.
-
- To start a new paragraph, insert an empty line, as shown above.
- This line, in contrast, will be in the same paragraph.
-
- In all sections you can insert some simple HTML code, such as <b>bold</b> or
- <i>italic</i> text. Please keep formatting to the minimum needed, however.
-
- The usage section is always the second section shown in a help page.
- </usage>
-
- <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. 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
-
- <link href="URL">link name</link>
-
- Where URL could be an external link such as http://rkward.sourceforge.net .
- Several special URLs are supported in the help pages:
-
- <link href="rkward://page/path/page_id"/>
-
- This links to a top level rkward help page (not for a plugin).
-
- <link href="rkward://component/[namespace/]component_id"/>
-
- This links to the help page of another plugin. The [namespace/] part may be omitted
- (in this case, rkward is assumed as the standard namespace, e.g.:
- <link href="rkward://component/import_spss"/> or
- <link href="rkward://component/rkward/import_spss"/> are equivalent).
- The component_id is the same that you specified in the <link linkend="pluginmap">.pluginmap</link>.
-
- <link href="rkward://rhelp/rfunction"/>
-
- Links to the R help page on "rfunction".
-
- Note that the link names will be generated automatically for these types of links.
- </section>
-
- <settings>
- <caption id="id_of_tab_or_frame"/>
- <setting id="id_of_element">
- Description of the GUI element identified by the given id
- </setting>
- <setting id="id_of_elementb" title="description">
- Usually the title of the GUI element will be extracted from the
- <link linkend="mainxml">XML definition of the plugin</link>, automatically. However,
- for some GUI elements, this description may not be enough to identify them, reliably.
- In this case, you can add an explicit title using the "title" attribute.
- </setting>
- <setting id="id_of_elementc">
- Description of the GUI element identified by "id_of_elementc"
- </setting>
- [...]
- </settings>
-
- <related>
- The related section typically just contains some links, such as:
-
- <ul>
- <li><link href="rkward://rhelp/mean"/></li>
- <li><link href="rkward://rhelp/median"/></li>
- <li><link href="rkward://component/related_component"/></li>
- </ul>
- </related>
-
- <technical>
- The technical section (optional, always last) may contain some technical details of the plugin
- implementation, which are of interest only to RKWard developers. This is particularly relevant
- for plugins that are designed to be embedded in many other plugins, and could detail, which
- options are available to customize the embedded plugin, and which code sections contain which
- R code.
- </technical>
- </document>
+<!DOCTYPE rkhelp>
+<document>
+ <summary>
+In this section, you'll put some short, very basic information about what the plugin does.
+This section will always show up on the very top of the help page.
+ </summary>
+
+ <usage>
+The usage section may contain a little more practical information. It does not explain all
+the settings in detail (that's done in the "settings" section), however.
+
+To start a new paragraph, insert an empty line, as shown above.
+This line, in contrast, will be in the same paragraph.
+
+In all sections you can insert some simple HTML code, such as <b>bold</b> or
+<i>italic</i> text. Please keep formatting to the minimum needed, however.
+
+The usage section is always the second section shown in a help page.
+ </usage>
+
+ <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. 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
+
+<link href="URL">link name</link>
+
+Where URL could be an external link such as http://rkward.sourceforge.net .
+Several special URLs are supported in the help pages:
+
+<link href="rkward://page/path/page_id"/>
+
+This links to a top level rkward help page (not for a plugin).
+
+<link href="rkward://component/[namespace/]component_id"/>
+
+This links to the help page of another plugin. The [namespace/] part may be omitted
+(in this case, rkward is assumed as the standard namespace, e.g.:
+<link href="rkward://component/import_spss"/> or
+<link href="rkward://component/rkward/import_spss"/> are equivalent).
+The component_id is the same that you specified in the <link linkend="pluginmap">.pluginmap</link>.
+
+<link href="rkward://rhelp/rfunction"/>
+
+Links to the R help page on "rfunction".
+
+Note that the link names will be generated automatically for these types of links.
+ </section>
+
+ <settings>
+ <caption id="id_of_tab_or_frame"/>
+ <setting id="id_of_element">
+Description of the GUI element identified by the given id
+ </setting>
+ <setting id="id_of_elementb" title="description">
+Usually the title of the GUI element will be extracted from the
+<link linkend="mainxml">XML definition of the plugin</link>, automatically. However,
+for some GUI elements, this description may not be enough to identify them, reliably.
+In this case, you can add an explicit title using the "title" attribute.
+ </setting>
+ <setting id="id_of_elementc">
+Description of the GUI element identified by "id_of_elementc"
+ </setting>
+ [...]
+ </settings>
+
+ <related>
+The related section typically just contains some links, such as:
+
+<ul>
+ <li><link href="rkward://rhelp/mean"/></li>
+ <li><link href="rkward://rhelp/median"/></li>
+ <li><link href="rkward://component/related_component"/></li>
+</ul>
+ </related>
+
+ <technical>
+The technical section (optional, always last) may contain some technical details of the plugin
+implementation, which are of interest only to RKWard developers. This is particularly relevant
+for plugins that are designed to be embedded in many other plugins, and could detail, which
+options are available to customize the embedded plugin, and which code sections contain which
+R code.
+ </technical>
+</document>
</programlisting>
</chapter>
<chapter id="logic">
-<title>GUI logic</title>
-<para>
-All the basic concepts of creating a plugin for &rkward; have been described in the previous chapters. Those basic concepts should be sufficient for many -- if not most -- cases. However, sometimes you want more control over how your plugin's GUI behaves.
-</para>
-<para>
-For instance, suppose you want to extend the t-test example used in this documentation to allow both: comparing a variable against another variable (as shown), and comparing a variable against a constant value. Now, one way of doing this would be to add a radio-control that switches between the two modes, and adding a spinbox to enter the constant value to compare against. Consider this simplified example:
-</para>
-<programlisting>
+<title>Logic interactions between GUI elements</title>
+<sect1 id="sect_GUI_logic"><title>GUI logic</title>
+ <para>
+ All the basic concepts of creating a plugin for &rkward; have been described in the previous chapters. Those basic concepts should be sufficient for many -- if not most -- cases. However, sometimes you want more control over how your plugin's GUI behaves.
+ </para>
+ <para>
+ For instance, suppose you want to extend the t-test example used in this documentation to allow both: comparing a variable against another variable (as shown), and comparing a variable against a constant value. Now, one way of doing this would be to add a radio-control that switches between the two modes, and adding a spinbox to enter the constant value to compare against. Consider this simplified example:
+ </para>
+ <programlisting>
<!DOCTYPE rkplugin>
<document>
<code file="code.js"/>
@@ -753,12 +783,11 @@
</row>
</dialog>
</document>
-</programlisting>
-<para>
-So far so good, but there are a number of problems with this GUI. First, both the varslot and the spinbox are always shown, whereas only one of the two is really used. Worse, the varslot always requires a valid selection, even if you compare against a constant. Obviously, if we create a multi-purpose GUI like this, we want more flexibility. Enter: the <logic>-section (inserted at the same level as <code>, <dialog>, or <wizard>).
-</para>
-<para>
-<programlisting>
+ </programlisting>
+ <para>
+ So far so good, but there are a number of problems with this GUI. First, both the varslot and the spinbox are always shown, whereas only one of the two is really used. Worse, the varslot always requires a valid selection, even if you compare against a constant. Obviously, if we create a multi-purpose GUI like this, we want more flexibility. Enter: the <command><logic></command> section (inserted at the same level as <command><code></command>, <command><dialog></command>, or <command><wizard></command>).
+ </para>
+ <programlisting>
[...]
<code file="code.js"/>
@@ -772,39 +801,43 @@
<dialog label="T-Test">
[...]
-</programlisting>
-</para>
-<para>
-The first two lines inside the logic section are <conver> tags. Those basically provide two new boolean (on or off, true or false) properties, which can be used later on. The first property (<quote>varmode</quote>) is true, whenever the upper radio button is selected and the second whenever the lower radio button is selected. How is this done?
-</para>
-<para>
- First, under <parameter>sources</parameter>, the source properties to work on are listed (in this case only one each; you could list several as <parameter>sources</parameter>=<replaceable>"mode.string;somethingelse"</replaceable>, then <quote>varmode</quote> would only be true, if both <quote>mode.string</quote> and <quote>somethingelse</quote> are equal to the string <quote>variable</quote>). Note that in this case we don't just write <quote>mode</quote> (as we would in <function>getValue("mode")</function>, but <quote>mode.string</quote>. This is actually the internal way a radio control works: It has a property <quote>string</quote>, which holds its string value. <function>getValue("mode")</function> is just a shorthand, and equivalent to <function>getValue("mode.string")</function>. See the reference for all properties of the different GUI elements.
-</para>
-<para>
- Second, we set the mode of conversion to <parameter>mode</parameter>=<replaceable>"equals"</replaceable>. This means, we want to check, whether the sources are equal to a certain value. Finally standard is the value to compare against, so with <parameter>standard</parameter>=<replaceable>"variable"</replaceable>, we check whether the property <quote>mode.string</quote> is equal to the string <quote>variable</quote> (the value of the upper radio option). If it is equal, then the property varmode is true, else it is false.
-</para>
-<para>
-The next line is basically the same, but reversed. Here we define a property (<quote>constmode</quote>) which becomes true, if the second radio option is selected.
-</para>
-<para>
-Now to the real stuff: We <connect> the <quote>varmode</quote> property to y.visible, which controls whether the varslot <quote>y</quote> is shown or not. Note that any element which is made invisible is implicitly non-required. Thus, if the upper radio-option is selected, the varslot <quote>y</quote> is required, and visible. Else it is not required and hidden.
-</para>
-<para>
-We do just the reverse for the spinbox. So in effect, either the varslot is shown and required, <emphasis>or</emphasis> the spinbox is shown and required - depending on which option is selected in the radio control. The GUI is changing itself according to the radio option. Try the example, if you like.
-</para>
-<note><para>
-In the above example, instead of defining two properties <quote>varmode</quote> and <quote>constmode</quote>, we could also have used the negation of <quote>varmode</quote>, like this:
-</para></note>
-<programlisting>
+ </programlisting>
+ <para>
+ The first two lines inside the logic section are <command><convert></command> tags. Those basically provide two new boolean (on or off, true or false) properties, which can be used later on. The first property (<replaceable>"varmode"</replaceable>) is true, whenever the upper radio button is selected and the second whenever the lower radio button is selected. How is this done?
+ </para>
+ <para>
+ First, under <parameter>sources</parameter>, the source properties to work on are listed (in this case only one each; you could list several as <parameter>sources=</parameter><replaceable>"mode.string;somethingelse"</replaceable>, then <replaceable>"varmode"</replaceable> would only be true, if both <replaceable>"mode.string"</replaceable> and <replaceable>"somethingelse"</replaceable> are equal to the string <replaceable>"variable"</replaceable>). Note that in this case we don't just write <replaceable>"mode"</replaceable> (as we would in <function>getValue("mode")</function>, but <replaceable>"mode.string"</replaceable>. This is actually the internal way a radio control works: It has a property <quote>string</quote>, which holds its string value. <function>getValue("mode")</function> is just a shorthand, and equivalent to <function>getValue("mode.string")</function>. See the reference for all properties of the different GUI elements.
+ </para>
+ <para>
+ Second, we set the mode of conversion to <parameter>mode=</parameter><replaceable>"equals"</replaceable>. This means, we want to check, whether the sources are equal to a certain value. Finally standard is the value to compare against, so with <parameter>standard=</parameter><replaceable>"variable"</replaceable>, we check whether the property <replaceable>"mode.string"</replaceable> is equal to the string <replaceable>"variable"</replaceable> (the value of the upper radio option). If it is equal, then the property varmode is true, else it is false.
+ </para>
+ <para>
+ The next line is basically the same, but reversed. Here we define a property (<replaceable>"constmode"</replaceable>) which becomes true, if the second radio option is selected.
+ </para>
+ <para>
+ Now to the real stuff: We <command><connect></command> the <replaceable>"varmode"</replaceable> property to y.visible, which controls whether the varslot <replaceable>"y"</replaceable> is shown or not. Note that any element which is made invisible is implicitly non-required. Thus, if the upper radio-option is selected, the varslot <replaceable>"y"</replaceable> is required, and visible. Else it is not required and hidden.
+ </para>
+ <para>
+ We do just the reverse for the spinbox. So in effect, either the varslot is shown and required, <emphasis>or</emphasis> the spinbox is shown and required - depending on which option is selected in the radio control. The GUI is changing itself according to the radio option. Try the example, if you like.
+ </para>
+ <note>
+ <para>
+ In the above example, instead of defining two properties <replaceable>"varmode"</replaceable> and <replaceable>"constmode"</replaceable>, we could also have used the negation of <replaceable>"varmode"</replaceable>, like this:
+ </para>
+ </note>
+ <programlisting>
<connect client="constant.visible" governor="varmode.not" />
-</programlisting>
-<para>
- Once again, for a complete list of properties, refer to the <link linkend="reference">reference</link>. One more property, however, is special in that all GUI elements have it: <quote>enabled</quote>. This is slightly less drastic that <quote>visible</quote>. It does not show/hide the GUI element, but only enables/disables it. Disabled elements are typically shown grayed out, and do not react to user input.
-</para>
+ </programlisting>
+ <para>
+ Once again, for a complete list of properties, refer to the <link linkend="reference">reference</link>. One more property, however, is special in that all GUI elements have it: <quote>enabled</quote>. This is slightly less drastic that <quote>visible</quote>. It does not show/hide the GUI element, but only enables/disables it. Disabled elements are typically shown grayed out, and do not react to user input.
+ </para>
+</sect1>
<sect1 id="logic_scripted">
<title>Scripted GUI logic</title>
-<para>While connecting properties as described above is often enough, sometimes it is more flexible or more convenient to use JS to script the GUI logic. In this way, the above example could be re-written as:</para>
-<programlisting>
+ <para>
+ While connecting properties as described above is often enough, sometimes it is more flexible or more convenient to use JS to script the GUI logic. In this way, the above example could be re-written as:
+ </para>
+ <programlisting>
[...]
<code file="code.js"/>
@@ -825,32 +858,35 @@
<dialog label="T-Test">
[...]
-</programlisting>
-<para>
-The first line of code tells &rkward; to call the function <function>modeChanged()</function> whenever the value of the <quote>mode</quote> radio-box changes. Inside this function, we define a helper-variable <quote>varmode</quote> which is true when the mode is <quote>variable</quote>, false is it is <quote>constant</quote>. Then we use <function>gui.setValue()</function> to set the and <quote>enabled</quote>-properties of <quote>y</quote> and <quote>constant</quote>, in just the same way as we did using <connect>-statements, before.</para>
-<para>
-The scripted approach to GUI logic becomes particularly useful when you want to change the available option according to the type of object that the user has selected. See <link linkend="guilogic_functions">the reference</link> for available functions.
-</para>
-<para>
-Note that the scripted approach to GUI logic can be mixed with <connect> and <convert>-statements if you like. Also note that the <script>-tag allows to specify a script file name in addition to or as an alternative to inlining the script code. Typically, inlining the script code as shown above is most convenient, however.
-</para>
+ </programlisting>
+ <para>
+ The first line of code tells &rkward; to call the function <function>modeChanged()</function> whenever the value of the <parameter>id=</parameter><replaceable>"mode"</replaceable> radio box changes. Inside this function, we define a helper-variable <replaceable>"varmode"</replaceable> which is true when the mode is <replaceable>"variable"</replaceable>, false is it is <replaceable>"constant"</replaceable>. Then we use <function>gui.setValue()</function> to set the and <quote>enabled</quote> properties of <replaceable>"y"</replaceable> and <replaceable>"constant"</replaceable>, in just the same way as we did using <command><connect></command> statements, before.
+ </para>
+ <para>
+ The scripted approach to GUI logic becomes particularly useful when you want to change the available option according to the type of object that the user has selected. See <link linkend="guilogic_functions">the reference</link> for available functions.
+ </para>
+ <para>
+ Note that the scripted approach to GUI logic can be mixed with <command><connect></command> and <command><convert></command>-statements if you like. Also note that the <command><script></command> tag allows to specify a script file name in addition to or as an alternative to inlining the script code. Typically, inlining the script code as shown above is most convenient, however.
+ </para>
</sect1>
</chapter>
<chapter id="embedding">
<title>Embedding Plugins into Plugins</title>
-<para>
-When writing plugins, you will often find that you're creating a number of plugins that only differ in some respects, but have a lot more in common. For instance, for plotting, there are a number of generic &r; options that can be used with mostly all types of plots. Should you create a GUI and JS-template for those over and over again?
-</para>
-<para>
-Obviously that would be quite a hassle. Fortunately, you don't have to do that. Rather you create the common functionality once, and later you can embed it into several plugins. In fact it is possible to embed any plugin into any other plugin, even if the original author of the embedded plugin never thought, somebody would want to embed their plugin into another one.
-</para>
+<sect1 id="sect_embedding"><title>Use cases for embedding</title>
+ <para>
+ When writing plugins, you will often find that you're creating a number of plugins that only differ in some respects, but have a lot more in common. For instance, for plotting, there are a number of generic &r; options that can be used with mostly all types of plots. Should you create a GUI and JS-template for those over and over again?
+ </para>
+ <para>
+ Obviously that would be quite a hassle. Fortunately, you don't have to do that. Rather you create the common functionality once, and later you can embed it into several plugins. In fact it is possible to embed any plugin into any other plugin, even if the original author of the embedded plugin never thought, somebody would want to embed their plugin into another one.
+ </para>
+</sect1>
<sect1 id="embedding_dialog">
<title>Embedding inside a dialog</title>
-<para>
-Ok, enough said. How does it work? Simple: Just use the <embed> tag. Here's a stripped down example:
-</para>
-<programlisting>
+ <para>
+ Ok, enough said. How does it work? Simple: Just use the <command><embed></command> tag. Here's a stripped down example:
+ </para>
+ <programlisting>
<dialog>
<tabbook>
<tab [...]>
@@ -864,36 +900,36 @@
</tab>
</tabbook>
</dialog>
-</programlisting>
-<para>
-What happens here, is that the entire GUI or the plot options plugin (except of course for the standard elements like <guibutton>Submit</guibutton> button, etc.) is embedded right into your plugin (try it!).
-</para>
-<para>
-As you can see the syntax of the <embed>-tag is fairly simple. It takes an id as most elements. The parameter component specifies which plugin to embed, as defined in the <link linkend="pluginmap">.pluginmap</link> file (<quote>rkward::plot_options</quote> is the result of concatenating the namespace <quote>rkward</quote>, a separator <quote>::</quote>, and the name of the component <quote>plot_options</quote>).
-</para>
+ </programlisting>
+ <para>
+ What happens here, is that the entire GUI or the plot options plugin (except of course for the standard elements like <guibutton>Submit</guibutton> button, etc.) is embedded right into your plugin (try it!).
+ </para>
+ <para>
+ As you can see the syntax of the <command><embed></command>-tag is fairly simple. It takes an <parameter>id</parameter> as most elements. The parameter component specifies which plugin to embed, as defined in the <link linkend="pluginmap">.pluginmap</link> file (<replaceable>"rkward::plot_options"</replaceable> is the result of concatenating the namespace <quote>rkward</quote>, a separator <quote>::</quote>, and the name of the component <quote>plot_options</quote>).
+ </para>
</sect1>
<sect1 id="embedding_code">
<title>Code generation when embedding</title>
-<para>
-So far so good, but what about the generated code? How are the code for the embedding and embedded plugin merged? In the embedding plugin's JS-code, simply write something like this:
-</para>
-<programlisting>
+ <para>
+ So far so good, but what about the generated code? How are the code for the embedding and embedded plugin merged? In the embedding plugin's JS code, simply write something like this:
+ </para>
+ <programlisting>
function printout () {
// ...
echo ("myplotfunction ([...]" + getValue ("plotoptions.code.printout"); + ")\n");
// ...
}
-</programlisting>
-<para>
-So essentially, we're fetching the code generated by the embedded plugin just like we're fetchting any other GUI setting. Here the string <quote>plotoptions.code.printout</quote> can be deparsed to: <quote>The printout section of the generated code of the element with the id plotoptions</quote> (plotoptions is the id we gave for the <embed>-tag above). And yes, if you want advanced control, you can even fetch the values of individual GUI elements inside the embedded plugin (but not the other way around, as the embedded plugin does not know anything about its surroundings).
-</para>
+ </programlisting>
+ <para>
+ So essentially, we're fetching the code generated by the embedded plugin just like we're fetchting any other GUI setting. Here the string <replaceable>"plotoptions.code.printout"</replaceable> can be deparsed to: <quote>The printout section of the generated code of the element with the <parameter>id</parameter> plotoptions</quote> (plotoptions is the ID we gave for the <command><embed></command> tag above). And yes, if you want advanced control, you can even fetch the values of individual GUI elements inside the embedded plugin (but not the other way around, as the embedded plugin does not know anything about its surroundings).
+ </para>
</sect1>
<sect1 id="embedding_wizard">
<title>Embedding inside a wizard</title>
-<para>
-If your plugin provides a wizard GUI, embedding works basically in the same way. You'll generally use:
-</para>
-<programlisting>
+ <para>
+ If your plugin provides a wizard GUI, embedding works basically in the same way. You'll generally use:
+ </para>
+ <programlisting>
<wizard [...]>
[...]
<page id="page12">
@@ -905,20 +941,20 @@
</page>
[...]
</wizard>
-</programlisting>
-<para>
-If the embedded plugin provides a wizard interface, its pages will be inserted right between page12 and page13 of your plugin. If the embedded plugin provides a dialog interface only, a single new page will be added between your pages page12 and page13. The user will never notice.
-</para>
+ </programlisting>
+ <para>
+ If the embedded plugin provides a wizard interface, its pages will be inserted right between <replaceable>"page12"</replaceable> and <replaceable>"page13"</replaceable> of your plugin. If the embedded plugin provides a dialog interface only, a single new page will be added between your pages <replaceable>"page12"</replaceable> and <replaceable>"page13"</replaceable>. The user will never notice.
+ </para>
</sect1>
<sect1 id="embedding_as_button">
-<title>Less embedded embedding: Further <guibutton>Options</guibutton> button</title>
-<para>
-While embedding is cool, you should be careful not to overdo it. Too many functions inside a GUI just make it hard to find the relevant options. Of course, sometimes you may want to embed a great deal of options (like all the options to <function>plot()</function>), but as those are really optional, you don't want them prominently in your GUI.
-</para>
-<para>
-An alternative is to embed those options "as a button":
-</para>
-<programlisting>
+<title>Less embedded embedding: Further Options button</title>
+ <para>
+ While embedding is cool, you should be careful not to overdo it. Too many functions inside a GUI just make it hard to find the relevant options. Of course, sometimes you may want to embed a great deal of options (like all the options to <function>plot()</function>), but as those are really optional, you don't want them prominently in your GUI.
+ </para>
+ <para>
+ An alternative is to embed those options <quote>as a button</quote>:
+ </para>
+ <programlisting>
<dialog>
<tabbook>
[...]
@@ -930,71 +966,77 @@
</tabbook>
</dialog>
</programlisting>
-<para>
@@ Diff output truncated at 100000 characters. @@
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