+=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 PRE FUNCTIONS
+
+Before a job runs, you can arrange that a C<pre> function is called.
+This function may decide not to run the job (by returning C<false>).
+
+One use for this is to prevent a particular job from running if there
+is already an instance of the same job running:
+
+ job "only one"
+ pre (Whentools.one ())
+ every 10 seconds :
+ <<
+ # Takes longer than 10 seconds to run, but 'Whentools.one ()'
+ # will ensure only one is ever running.
+ sleep 11
+ >>
+
+When using pre functions, jobs must be given an explicit name, ie.
+you must use the C<job> statement.
+
+A number of pre 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.preinfo> struct, defined
+below. It should return a boolean: C<true> if the job should run, and
+C<false> if the job should not run.
+
+Note that a fresh serial number (see L</JOBSERIAL>) is assigned to
+each run, whether or not the job actually runs because of
+preconditions.
+
+=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.max> I<n>
+
+This built-in pre function ensures that a maximum of I<n> instances of
+the job are running.
+
+It checks the list of running jobs, and if I<n> or more instances are
+already running, then it returns C<false>, which ensures that the new
+job is not started.
+
+=item B<Whentools.one> I<()>
+
+This built-in pre function ensures that only one instance of the job
+is running. It is the same as calling:
+
+ Whentools.max 1