+B<Note:> There is a subtle gotcha with the I<decreases> operator: The
+first time the expression is evaluated, the job has (by definition)
+not yet run. Therefore C<prev variable> evaluates to C<""> (see
+definition of I<prev> above). Since it is always true that
+
+ "" < anything
+
+the I<decreases> operator evaluates to false, and since this usually
+means the job does not run, the operator always evaluates to false.
+
+To fix this, ensure that the variable is initialized (see
+L</SETTING THE INITIAL VALUE OF VARIABLES> below).
+
+=item B<reloaded ()>
+
+This evaluates to true the first time the expression is evaluated
+after the jobs file has been reloaded or the daemon restarted.
+Thereafter it evaluates to false.
+
+Don't use this to initialize variables: it won't do what you mean.
+
+=item B<false>
+
+=item B<true>
+
+Constants that evaluate to boolean false or true respectively.
+
+=item I<"any string">
+
+Any string.
+
+In a boolean context, the empty string evaluates to false, and
+non-empty strings evaluate to true.
+
+=item I<N>
+
+Any integer. (Arbitrarily large integers are supported.)
+
+In a boolean context, 0 evaluates to false, and non-zero evaluates to
+true.
+
+=item I<N.>
+
+=item I<.N>
+
+=item I<N.N>
+
+=item I<N.NeN>
+
+Any floating point number.
+
+In a boolean context, 0 evaluates to false, and non-zero evaluates to
+true.
+
+=back
+
+=head2 SHELL SCRIPTS
+
+The code between C<E<lt>E<lt> ... E<gt>E<gt>> is a shell script. It
+is executed using C<$SHELL>, or if that environment variable is not
+set then C</bin/sh>.
+
+=head3 SHELL SCRIPT VARIABLES
+
+Every variable that has been set (using the whenjobs I<--set> option)
+is exported to the script, so you can simply get the value of any
+variable by writing C<$name>.
+
+In addition, there are some special variables available:
+
+=over 4
+
+=item C<$JOBNAME>
+
+The name of the job. If the job has been named explicitly, then that
+name is available through this variable, else it will be some implicit
+name like C<job$1>.
+
+=item C<$JOBSERIAL>
+
+The serial number of the job. This is simply a variable that
+increments each time a job is run, and is unique to that run of the
+job.
+
+=back
+
+Other environment variables such as C<$HOME>, C<$LOGNAME> etc are
+available as normal.
+
+=head3 SHELL SCRIPT TEMPORARY CURRENT DIRECTORY
+
+The shell script runs with its current directory set to a temporary
+directory. The temporary directory is removed when the shell script
+exits. Therefore you can write temporary files here without worrying
+about cleaning them up.
+
+If you want to store permanent state, then you have to save it to a
+well-known directory, eg. C<$HOME>, C</var> etc.
+
+=head3 SHELL SCRIPT USER
+
+The shell script runs as the ordinary user. It has no special
+privileges.
+
+=head2 JOB NAMES
+
+Jobs are given implicit names (C<job$1>, C<job$2> etc.). You can also
+name jobs explicitly by preceeding the "every" or "when" statement
+with C<job "name">:
+
+ job "poll source"
+ every 10 seconds :
+ <<
+ # ...
+ >>
+
+The job name is passed to the shell script in the C<$JOBNAME>
+environment variable.
+
+=head2 OCAML EXPRESSIONS
+
+As well as simple "every" and "when" expressions, advanced users may
+want to use arbitrary OCaml expressions, functions, etc in the jobs
+script. These are useful for factoring common code or strings, for
+setting the initial values of variables, or for defining pre and post
+functions.
+
+A simple example of an OCaml expression is:
+
+ let prefix = "daily_"
+
+ job (prefix ^ "virus_scan")
+ every day :
+ <<
+ # ...
+ >>
+
+ job (prefix ^ "disk_check")
+ every day :
+ <<
+ # ...
+ >>
+
+which creates two jobs called C<"daily_virus_scan"> and
+C<"daily_disk_check"> (C<^> is the OCaml string concatenation
+operator).
+
+OCaml expressions have access to a library of functions called
+B<Whentools> which is described below. It lets you set variables,
+create jobs algorithmically, etc.
+
+The OCaml expressions run once, when the jobs file is being loaded or
+reloaded.
+
+=head3 SETTING THE INITIAL VALUE OF VARIABLES
+
+Variables are created when they are referenced, and until set they
+have the value empty string (just like the shell). Across file
+reloads, the previous values of variables are preserved.
+
+To initialize a variable to a known value when the jobs file is
+loaded, call one of the C<Whentools.set_variable*> functions as in
+this example:
+
+ let () =
+ Whentools.set_variable "name" "Richard";
+ Whentools.set_variable_int "counter" 0
+
+=head3 POST FUNCTIONS
+
+After a job runs, you can control what happens to its output by
+writing a C<post> function. To write a post function you have to
+name the job (ie. have an explicit C<job> statement). Put C<post ...>
+after the job name like this:
+
+ job "poll source"
+ post (Whentools.mailto "you@example.com")
+ every 10 seconds :
+ <<
+ # ...
+ >>
+
+A number of post functions are available in the library; see below.
+
+You can also write your own post functions (in OCaml). The
+function is passed one argument which is a C<Whentools.result> struct,
+defined below.
+
+=head3 WHENTOOLS LIBRARY
+
+=head4 Functions
+
+=over 4
+
+=item B<Whentools.mailto> [I<~only_on_failure:true>]
+[I<~from:from_address>] I<email_address> I<result>
+
+This built-in post function sends the result of the script by email to
+the given email address.
+
+If the optional C<~only_on_failure:true> flag is set, then it is only
+sent out if the script failed.
+
+If the optional C<~from> flag is set, then the from address is set
+accordingly. This is sometimes needed when sending mail.
+
+Note the C<result> parameter is passed implicitly by the daemon. You
+do not need to add it.
+
+Here are some examples of using the mailto function:
+
+ job "ex.1"
+ post (Whentools.mailto "you@example.com")
+ every 10 seconds :
+ <<
+ # do something
+ >>
+
+ job "ex.2"
+ post (Whentools.mailto ~only_on_failure:true
+ "you@example.com")
+ every 10 seconds :
+ <<
+ # do something
+ >>
+
+ let from = "me@example.com"
+ let to_addr = "you@example.com"
+
+ job "ex.3"
+ post (Whentools.mailto ~from to_addr)
+ every 10 seconds :
+ <<
+ # do something
+ >>
+
+=item B<Whentools.set_variable> I<name> I<string>
+
+Set variable I<name> to the string.
+
+=item B<Whentools.set_variable_bool> I<name> I<b>
+
+Set variable I<name> to the boolean value I<b>.
+
+=item B<Whentools.set_variable_int> I<name> I<i>
+
+Set variable I<name> to the integer value I<i>.
+
+=item B<Whentools.set_variable_string> I<name> I<s>
+
+Set variable I<name> to the string value <s>. This is
+the same as I<Whentools.set_variable>.
+
+=item B<Whentools.set_variable_float> I<name> I<f>
+
+Set variable I<name> to the floating point value I<f>.
+
+=back
+
+=head4 Structures
+
+=over 4
+
+=item B<Whentools.result>
+
+This structure is passed to post functions. It has the following
+fields:
+
+ type result = {
+ res_job_name : string; # job name
+ res_serial : big_int; # job serial (same as $JOBSERIAL)
+ res_code : int; # return code from the shell script
+ res_tmpdir : string; # temporary directory script ran in
+ res_output : string; # filename of stdout/stderr output
+ res_start_time : float; # when the job started
+ }
+
+=back