Man Linux: Main Page and Category List

NAME

       remind - a sophisticated reminder service

SYNOPSIS

       remind [options] filename [date] [*rep] [time]

DESCRIPTION

       Remind  reads  the supplied filename and executes the commands found in
       it.  The commands  are  used  to  issue  reminders  and  alarms.   Each
       reminder  or alarm can consist of a message sent to standard output, or
       a program to be executed.

       If filename is specified as a single dash ’-’, then  Remind  takes  its
       input from standard input.  This also implicitly enables the -o option,
       described below.

       If filename happens to be a directory rather than a  plain  file,  then
       Remind  reads all of the files in that directory that match the pattern
       "*.rem".  The files are read in sorted order; the sort order may depend
       on  your  locale,  but should match the sort order used by the shell to
       expand "*.rem".

OPTIONS

       Remind has a slew of options.  If you’re new  to  the  program,  ignore
       them for now and skip to the section "Reminder Files".

       -n     The -n option causes Remind to print the next occurrence of each
              reminder in a simple calendar format.  You can sort this by date
              by piping the output through sort(1).

       -r     The  -r option disables RUN directives and the shell() function.
              As of Remind 3.00.17, using -u implies -r.

       -c[flags]n
              The -c option causes Remind to produce a calendar that  is  sent
              to  standard  output.  If you supply a number n, then a calendar
              will be generated for n months, starting with the current month.
              By default, a calendar for only the current month is produced.

       You  can  precede  n  (if  any)  with a set of flags.  The flags are as
       follows:

       ’+’    causes a calendar for n weeks to be produced.

       ’a’    causes Remind to display reminders on the calendar  on  the  day
              they  actually  occur as well as on any preceding days specified
              by the reminder’s delta.

       ’l’    causes Remind to use VT100 line-drawing characters to  draw  the
              calendar.   The  characters are hard-coded and will only work on
              terminals that emulate the VT00 line-drawing character set.

       ’c’    causes Remind to  use  VT100  escape  sequences  to  approximate
              SPECIAL  COLOR  reminders.   The approximation is (of necessity)
              very coarse, because the VT100 only has  eight  different  color
              sequences, each with one of two brightnesses.  A color component
              greater than 64 is considered "on", and  if  any  of  the  three
              color  components  is  greater than 128, the color is considered
              "bright".

       -wcol[,pad[,spc]]]
              The -w option specifies the output width, padding and spacing of
              the  formatted  calendar  output.   Col  specifies the number of
              columns in the output device, and defaults to 80.  Pad specifies
              how  many  lines  to  use  to  "pad" empty calendar boxes.  This
              defaults to 5.  If you have many reminders on certain days  that
              make  your  calendar  too  large  to  fit on a page, you can try
              reducing pad to make the empty boxes smaller.  Spc specifies how
              many  blank  lines to leave between the day number and the first
              reminder entry.  It defaults to 1.

              Any of col, pad or spc can be omitted, providing you provide the
              correct number of commas.  Don’t use any spaces in the option.

       -s[a]n The  -s option is very similar to the -c option, except that the
              output calendar is not formatted.  It is  listed  in  a  "simple
              format"  that  can  be  used  as  input  for  more sophisticated
              calendar-drawing programs.  If n starts with  "+",  then  it  is
              interpreted as a number of weeks.

              If  you  immediately follow the s with the letter a, then Remind
              displays reminders on the calendar  on  the  day  they  actually
              occur  as  well  as  on  any  preceding  days  specified  by the
              reminder’s delta.

       -p[a]n The -p option is very similar to the -s option, except that  the
              output  contains  additional  information  for use by the Rem2PS
              program, which creates a PostScript calendar.  For this  option,
              n  cannot  start  with  "+"; it must specify a number of months.
              The format of the -p output is described in  the  rem2ps(1)  man
              page.   If  you immediately follow the p with the letter a, then
              Remind displays reminders  on  the  calendar  on  the  day  they
              actually occur as well as on any preceding days specified by the
              reminder’s delta.

       -l     If you use the -l option in conjunction with the -p option, then
              Remind outputs additional information for back-end programs such
              as  rem2ps.   This  additional  information  lets  the  back-end
              programs  correlate  a  reminder  with  the source file and line
              number that produced it.

       -m     The -m option causes the -c or -p options to produce a  calendar
              whose first column is Monday rather than Sunday.  (This conforms
              to the international standard.)

       -v     The -v option makes the output of Remind slightly more  verbose.
              Currently,  this  causes Remind to echo a bad line in case of an
              error, and to print a security message if  a  script  tests  the
              $RunOff system variable.

       -o     The -o option causes Remind to ignore all ONCE directives.

       -t     The   -t   option  causes  Remind  to  trigger  all  non-expired
              reminders, regardless of the delta supplied for each reminder.

       -tn    If you supply a number  n  after  the  -t  option,  then  Remind
              pretends  that  each  non-expired reminder has a delta of n days
              and triggers reminders accordingly.

       -h     The  -h  option  ("hush...")  suppresses  certain  warning   and
              information  messages.   In  particular,  if  no  reminders  are
              triggered, this mode produces no output.

       -a     The -a option causes Remind not  to  immediately  trigger  timed
              reminders  that would also be queued.  It also causes Remind not
              to place timed reminders in a calendar.

       -q     The -q option causes Remind not to  queue  timed  reminders  for
              later execution.

       -f     The  -f  option  causes  Remind to remain in the foreground when
              processing  queued  reminders,  rather  than   forking   off   a
              background process to handle them.

       -e     The  -e  option  diverts  error  messages  (normally sent to the
              standard error stream) to the standard output stream.

       -dchars
              The -d  option  enables  certain  debugging  modes.   The  chars
              specify which modes to enable:

         e      Echo all input lines

         x      Trace all expression evaluation

         t      Display all trigger date computation

         v      Dump the variable table after execution of the reminder script

         l      Echo lines when displaying error messages

         f      Trace the reading of reminder files

       -g[a|d[a|d[a|d]]]
              Normally, reminders are issued in the order in  which  they  are
              encountered  in the reminder script.  The -g option cause Remind
              to sort reminders by date and time prior to issuing  them.   The
              optional a and d characters specify the sort order (ascending or
              descending) for the date, time and  priority  fields.   See  the
              section "Sorting Reminders" for more information.

       -b[n]  Set  the  time  format  for  the  calendar  and  simple-calendar
              outputs.  N can range from 0 to 2, with the default 0.  A  value
              of  0  causes times to be inserted in 12-hour (am/pm) format.  1
              causes times to be inserted in 24-hour format,  and  2  inhibits
              the automatic insertion of times in the calendar output.

       -x[n]  Sets  the  iteration  limit  for  the  SATISFY  clause  of a REM
              command.  Defaults to 150.

       -kcmd  Instead of simply printing MSG-type reminders, this causes  them
              to  be  passed to the specific cmd.  You must use ’%s’ where you
              want the body to appear, and may need to enclose this option  in
              quotes.   Note  that  all  shell  characters  in the body of the
              reminder are escaped with a backslash, and the  entire  body  of
              the  reminder  is  passed  as a single argument.  Note that this
              option overrides the -r option and the RUN OFF command.

              As an example, suppose you  have  an  X  Window  program  called
              xmessage  that  pops  up  a  window  and displays its invocation
              arguments.  You could use:

                        remind ’-kxmessage %s &’ ...

              to have all of your MSG-type reminders processed using xmessage.

              A  word of warning:  It is very easy to spawn dozens of xmessage
              processes with the above technique.  So be very careful.   Also,
              the  cmd  is  passed  as  an  argument to sprintf().  If you use
              formatting directives other than %s, or use  more  than  one  %s
              directive,  there’s  a  good  chance  that  you’ll crash Remind.
              Finally,  because  all  shell  and  whitespace  characters   are
              escaped,  the  program  you  execute  with the -k option must be
              prepared to handle the entire message as a single argument.

       -z[n]  Runs Remind in the daemon mode.  If n is supplied, it  specifies
              how  often  (in  minutes)  Remind should wake up to check if the
              reminder script has been changed.  N  defaults  to  5,  and  can
              range  from  5  to  60.  Note that the use of the -z option also
              enables the -f option.

              If you supply the option -z0, Remind  runs  in  a  special  mode
              called  server  mode.   This  is  documented in the tkremind man
              page; see tkremind(1).

       -uname Runs Remind with the uid and gid of the user specified by  name.
              The  option  changes  the uid and gid as described, and sets the
              environment  variables  HOME,  SHELL  and  USER  to   the   home
              directory,  shell, and user name, respectively, of the specified
              user.  LOGNAME is also set to the  specified  user  name.   This
              option  is meant for use in shell scripts that mail reminders to
              all users.  Note that as of Remind 3.00.17, using -u implies  -r
              -- the RUN directive and shell() functions are disabled.

              Non-root  users  can  also  use the -u option.  However, in this
              case, it only changes the  environment  variables  as  described
              above.  It does not change the effective uid or gid.

       -y     Causes  Remind to synthesize a tag for any reminder that lacks a
              TAG clause.

       -ivar=expr
              Sets the value of the specified var to expr, and preserves  var.
              Expr  can  be  any  valid  Remind  expression.   See the section
              "Initializing Variables on the Command Line" for more details.

       -ifunc(args)=definition
              Allows you to define a function on the command line.

       If you supply a date on the command line, it must consist of day  month
       year,  where  day  is the day of the month, month is at least the first
       three letters of the English name of the month, and year is a year (all
       4  digits)  from  1990 to about 2075.  You can leave out the day, which
       then defaults to 1.

       If you do supply a date on the  command  line,  then  Remind  uses  it,
       rather  than  the  actual  system date, as its notion of "today."  This
       lets you create calendars for future months, or test to  see  how  your
       reminders will be triggered in the future.  Similarly, you can supply a
       time (in 24-hour format -- for example, 17:15) to set  Remind’s  notion
       of  "now"  to  a particular time.  Supplying a time on the command line
       also implicitly enables the -q option and disables the -z option.

       In addition, you can supply a repeat  parameter,  which  has  the  form
       *num.   This  causes  Remind  to  be  run  num  times,  with  the  date
       incrementing on each iteration.  You may have to enclose the  parameter
       in  quotes  to  avoid  shell  expansion.   See the subsection "Repeated
       Execution" in the section "Calendar Mode" for more information.

REMINDER FILES

       Remind uses scripts to control its operation.  You  can  use  any  text
       editor capable of creating plain ASCII files to create a Remind script.
       The commands inside a script can range from the very simple and  almost
       immediately understandable:

            REM 6 Jan MSG David’s birthday

       to the baroque and obscure:

            REM [trigger(date(thisyear, 1, 1) + 180)] ++5 OMIT \
            sat sun BEFORE MSG [ord(thisyear-1980)] payment due %b!

       A  reminder  file  consists  of  commands,  with  one command per line.
       Several lines can be continued using the backslash character, as in the
       above example.  In this case, all of the concatenated lines are treated
       as a single line by Remind.  Note  that  if  an  error  occurs,  Remind
       reports the line number of the last line of a continued line.

       Remind  ignores  blank  lines,  and lines beginning with the ’#’ or ’;’
       characters.  You can use the semicolon as a comment  character  if  you
       wish  to  pass  a  Remind  script  through  the  C pre-processor, which
       interprets  the  ’#’  character  as  the  start  of  a   pre-processing
       directive.

       Remind  is  not  case  sensitive;  you can generally use any mixture of
       upper- or lower-case for commands, parameters, invocation options, etc.

THE REM COMMAND

       The  most powerful command in a Remind script is the REM command.  This
       command is responsible for issuing reminders.  Its syntax is:

              REM [ONCE] [date_spec] [back] [delta] [repeat]  [PRIORITY  prio]
              [SKIP  |  BEFORE  |  AFTER]  [OMIT  omit_list] [AT time [tdelta]
              [trepeat]] [SCHED sched_function]  [WARN  warn_function]  [UNTIL
              expiry_date]  [SCANFROM  scan_date  | FROM start_date] [DURATION
              duration] [TAG tag] <MSG | MSF | RUN | CAL | SATISFY  |  SPECIAL
              special | PS | PSFILE> body

       The parts of the REM command can be specified in any order, except that
       the body must come immediately after the MSG, RUN, CAL, PS,  PSFILE  or
       SATISFY keyword.

       The  REM token is optional, providing that the remainder of the command
       cannot be mistaken for another Remind command such as OMIT or RUN.  The
       portion  of  the  REM  command  before the MSG, MSF RUN, CAL or SATISFY
       clause is called a trigger.

       MSG, MSF, RUN, CAL, SPECIAL, PS and PSFILE

       These keywords denote the type  of  the  reminder.   (SATISFY  is  more
       complicated and will be explained later.)  A MSG-type reminder normally
       prints a message to the standard output, after passing the body through
       a   special   substitution   filter,  described  in  the  section  "The
       Substitution Filter."  However, if you have used  the  -k  command-line
       option,  then MSG-type reminders are passed to the appropriate program.
       Note that the options -c, -s, -p and -n disable the -k option.

       Note that you can omit the reminder type, in which case it defaults  to
       MSG.  So you can write:

            6 January David’s Birthday

       although this is not recommended.

       The  MSF keyword is almost the same as the MSG keyword, except that the
       reminder is formatted to  fit  into  a  paragraph-like  format.   Three
       system  variables  control  the formatting of MSF-type reminders - they
       are $FirstIndent, $SubsIndent and $FormWidth.  They  are  discussed  in
       the  section "System Variables."  The MSF keyword causes the spacing of
       your reminder to be altered -  extra  spaces  are  discarded,  and  two
       spaces  are  placed after periods and other characters, as specified by
       the system variables $EndSent and $EndSentIg.  Note that if the body of
       the  reminder  includes  newline  characters  (placed there with the %_
       sequence), then the newlines are  treated  as  the  beginnings  of  new
       paragraphs, and the $FirstIndent indentation is used for the next line.
       You can use two consecutive newlines to have spaced paragraphs  emitted
       from a single reminder body.

       A  RUN-type  reminder  also  passes  the  body through the substitution
       filter, but then executes the result as a system command.   A  CAL-type
       reminder  is  used  only to place entries in the calendar produced when
       Remind is run with the -c, -s or -p options.

       A PS or PSFILE-type reminder is used to pass PostScript  code  directly
       to  the  printer when producing PostScript calendars.  This can be used
       to shade certain calendar entries (see the psshade() function), include
       graphics in the calendar, or almost any other purpose you can think of.
       You should not use these types of reminders unless you  are  an  expert
       PostScript  programmer.  The PS and PSFILE reminders are ignored unless
       Remind is run  with  the  -p  option.   See  the  section  "More  about
       PostScript" for more details.

       A  SPECIAL-type reminder is used to pass "out-of-band" information from
       Remind to a calendar-producing back-end.  It should be  followed  by  a
       word  indicating  the type of special data being passed.  The type of a
       special reminder depends on the back-end.   For  the  Rem2PS  back-end,
       SPECIAL  PostScript  is  equivalent  to a PS-type reminder, and SPECIAL
       PSFile is equivalent to a PSFILE-type reminder.  The body of a  SPECIAL
       reminder is obviously dependent upon the back-end.

       DATE SPECIFICATIONS

       A  date_spec  consists of zero to four parts.  These parts are day (day
       of month), month (month name), year and weekday.  Month and weekday are
       the  English  names  of  months and weekdays.  At least the first three
       characters must be used.  The following are  examples  of  the  various
       parts of a date_spec:

       day:   1, 22, 31, 14, 3

       month: JANUARY, feb, March, ApR, may, Aug

       year:  1990,  1993, 2030, 95 (interpreted as 1995).  The year can range
              from 1990 to 2075.

       weekday:
              Monday, tue, Wed, THU, Friday, saturday, sundAy

       Note that there can be several weekday components separated  by  spaces
       in a date_spec.

       INTERPRETATION OF DATE SPECIFICATIONS

       The following examples show how date specifications are interpreted.

       1.  Null date specification - the reminder is triggered every day.  The
       trigger date for a specific run is simply the current system date.

       2. Only day present.  The reminder is triggered on the specified day of
       each  month.  The trigger date for a particular run is the closest such
       day to the current system date.  For example:
            REM 1 MSG First of every month.
            REM 31 MSG 31st of every month that has 31 days.

       3. Only month present.  The reminder is  triggered  every  day  of  the
       specified month.  Example:
            REM Feb MSG Every day in February

       4.  day and month present.  Examples:
            REM 6 Jan MSG Every 6th of January
            REM Feb 29 MSG Every 29th of February

       5.  Only year present. Example:
            REM 1991 MSG Every day in 1991

       6.  year and day present.  Examples:
            REM 1 1990 MSG 1st of every month in 1990
            REM 1992 23 MSG 23rd of every month in 1992

       7.  year and month present.  Examples:
            REM Feb 1991 MSG Every day in Feb 1991
            REM 1992 September MSG Every day in Sept 1992

       8.  year, month and day present.  Examples:
            REM 8 Jan 1991 MSG 8th January 1991.
            REM 1992 March 9 MSG 9th March 1992.

       9.  weekday only.  Examples:
            REM Sat MSG Every Saturday
            REM Mon Tue Wed Thu Fri MSG Every working day
            REM Monday Wednesday MSG Every Monday and Wednesday

       10.  weekday and day present.  Examples:
            REM Sat 1 MSG First Saturday of every month
            REM Mon Tue Wed Thu Fri 15 \
                 MSG 1st working day after 15th of every month

       11.  weekday and month present.  Examples:
            REM Mon March MSG Every Monday in March
            REM Mon Tue Wed Thu Fri Feb MSG Every working day in February

       12.  weekday, month and day present.  Examples:
            REM Mon 1 March MSG First Monday in March
            REM Sat Sun 15 July MSG First Sat or Sun on or after 15 July

       13.  weekday and year present.  Example:
            REM Sat Sun 1991 MSG Every Saturday and Sunday in 1991

       14.  weekday, day and year present.  Examples:
            REM Mon 15 1990 MSG 1st Mon after 15th of every month in 1990
            REM Mon Tue Wed Thu Fri 1 1990 \
                 MSG 1st working day of every month in 1990

       15.  weekday, month and year present.  Example:
            REM Mon Wed 1991 Feb MSG Every Mon and Wed in Feb 1991.

       16.  weekday, day, month and year present.  Example:
            REM Mon Tue Wed Thu Fri 28 Oct 1990 \
                 MSG 1st working day on or after 28 October 1990.

       Note  that  when both weekday and day are specified, Remind chooses the
       first date on or after  the  specified  day  that  also  satisfies  the
       weekday constraint.  It does this by picking the first date on or after
       the specified day that is listed in the  list  of  weekdays.   Thus,  a
       reminder like:

            REM Mon Tue 28 Oct 1990 MSG Hi

       would  be  issued  only  on  Monday, 29 October, 1990.  It would not be
       issued on Tuesday, 30 October, 1990, since the 29th is the  first  date
       to satisfy the weekday constraints.

       BACKWARD SCANNING

       Sometimes,  it  is necessary to specify a date as being a set amount of
       time before another date.  For example, the  last  Monday  in  a  given
       month  is computed as the first Monday in the next month, minus 7 days.
       The back specification in the reminder is used in this case:

            REM Mon 1 -7 MSG Last Monday of every month.

       A back is specified with one or two  dashes  followed  by  an  integer.
       This  causes Remind to move "backwards" from what would normally be the
       trigger date.  The difference between --7 and -7 will be explained when
       the OMIT keyword is described.

       ADVANCE WARNING

       For some reminders, it is appropriate to receive advance warning of the
       event.  For example, you may wish to be reminded of someone’s  birthday
       several days in advance.  The delta portion of the REM command achieves
       this.  It is specified as one or two "+" signs followed by a number  n.
       Again,  the difference between the "+" and "++" forms will be explained
       under the OMIT keyword.  Remind will trigger the reminder  on  computed
       trigger  date, as well as on each of the n days before the event.  Here
       are some examples:

            REM 6 Jan +5 MSG Remind me of birthday 5 days in advance.

       The above example would be triggered every 6th of January, as  well  as
       the 1st through 5th of January.

       PERIODIC REMINDERS

       We  have  already  seen  some  built-in mechanisms for certain types of
       periodic reminders.  For example, an event  occurring  every  Wednesday
       could be specified as:

            REM Wed MSG Event!

       However,  events  that  do  not repeat daily, weekly, monthly or yearly
       require another approach.  The repeat  component  of  the  REM  command
       fills  this need.  To use it, you must completely specify a date (year,
       month and day, and optionally weekday.)  The  repeat  component  is  an
       asterisk followed by a number specifying the repetition period in days.

       For example, suppose you get paid every second Wednesday, and your last
       payday was Wednesday, 28 October, 1992.  You can use:

            REM 28 Oct 1992 *14 MSG Payday

       This  issues  the  reminder every 14 days, starting from the calculated
       trigger date.  You can use delta and back with repeat.  Note,  however,
       that  the  back  is  used  only  to  compute  the initial trigger date;
       thereafter, the reminder repeats with the specified period.  Similarly,
       if  you  specify  a  weekday,  it is used only to calculate the initial
       date, and does not affect the repetition period.

       SCANFROM and FROM

       The SCANFROM and FROM keywords  are  for  advanced  Remind  programmers
       only,  and  will  be  explained  in  the section "Details about Trigger
       Computation" near the end  of  this  manual.   Note  that  SCANFROM  is
       available  only  in  versions  of  Remind  from  03.00.04  up.  FROM is
       available only from 03.01.00 and later.

       PRIORITY

       The PRIORITY keyword must be followed by a number from 0 to  9999.   It
       is  used in calendar mode and when sorting reminders.  If two reminders
       have the same trigger date and time, then they are sorted by  priority.
       If  the PRIORITY keyword is not supplied, a default priority of 5000 is
       used.  (This default can be changed by adjusting  the  system  variable
       $DefaultPrio.    See   the   section   "System   Variables"   for  more
       information.)

       EXPIRY DATES

       Some reminders should be issued periodically for a  certain  time,  but
       then  expire.   For example, suppose you have a class every Friday, and
       that your last class is on 11 December 1992.  You can use:

            REM Fri UNTIL 11 Dec 1992 MSG Class today.

       Another example:  Suppose you have jury  duty  from  30  November  1992
       until  4  December 1992.  The following reminder will issue the message
       every day of your jury duty, as well as 2 days ahead of time:

            REM 30 Nov 1992 *1 +2 UNTIL 4 Dec 1992 MSG Jury duty

       Note that the repeat of *1 is necessary; without it, the reminder would
       be issued only on 30 November (and the two days preceding.)

       THE ONCE KEYWORD

       Sometimes,  it  is necessary to ensure that reminders are run only once
       on a given day.  For example, if you  have  a  reminder  that  makes  a
       backup of your files every Friday:

            REM Fri RUN do_backup

       (Here,  do_backup  is assumed to be a program or shell script that does
       the work.)  If you run Remind from your .login script, for example, and
       log  in  several  times per day, the do_backup program will be run each
       time you log in.   If,  however,  you  use  the  ONCE  keyword  in  the
       reminder,  the  Remind  checks  the  last  access  date of the reminder
       script.  If it is the same as the current date, Remind assumes that  it
       has  already been run, and will not issue reminders containing the ONCE
       keyword.

       Note that if you view or edit your reminder  script,  the  last  access
       date  will  be updated, and the ONCE keyword will not operate properly.
       If you start Remind with the -o option, then the ONCE keyword  will  be
       ignored.

       LOCALLY OMITTING WEEKDAYS

       The OMIT portion of the REM command is used to "omit" certain days when
       counting the delta or back.  It is specified  using  the  keyword  OMIT
       followed  by  a  list of weekdays.  Its action is best illustrated with
       examples:

            REM 1 +1 OMIT Sat Sun MSG Important Event

       This reminder is normally triggered on the first  of  every  month,  as
       well as the day preceding it.  However, if the first of the month falls
       on a Sunday or Monday, then the reminder is triggered starting from the
       previous  Friday.   This  is  because  the  delta  of +1 does not count
       Saturday or Sunday when it counts backwards from the  trigger  date  to
       determine how much advance warning to give.

       Contrast  this  with  the  use  of "++1" in the above command.  In this
       case, the reminder is triggered on the first of each month, as well  as
       the day preceding it.  The omitted days are counted.

            REM 1 -1 OMIT Sat Sun MSG Last working day of month

       Again, in the above example, the back of -1 normally causes the trigger
       date to be the last day of the month.  However,  because  of  the  OMIT
       clause,  if  the  first  of  the month falls on a Sunday or Monday, the
       trigger date is moved backwards past the weekend to  Friday.   (If  you
       have  globally  omitted  holidays, the reminder will be moved back past
       them, also.  See "The OMIT command" for more details.)

       By comparison, if we had used "--1", the reminder would be triggered on
       the last day of the month, regardless of the OMIT.

       TIMED REMINDERS

       Timed  reminders  are  those that have an AT keyword followed by a time
       and optional tdelta and trepeat.  The time must be specified in 24-hour
       format,  with  0:00 representing midnight, 12:00 representing noon, and
       23:59 representing one minute to midnight.  You can use either a  colon
       or a period to separate the hours from the minutes.  That is, 13:39 and
       13.39 are equivalent.

       Remind treats timed reminders specially.  If the  trigger  date  for  a
       timed  reminder is the same as the current system date, the reminder is
       queued for later activation.  When Remind has finished  processing  the
       reminder  file,  it  puts itself in the background, and activates timed
       reminders when the system time reached the specified time.

       If the trigger date is not the same as the system date, the reminder is
       not queued.

       For  example, the following reminder, triggered every working day, will
       emit a message telling you to leave at 5:00pm:

            REM Mon Tue Wed Thu Fri AT 17:00 MSG Time to leave!

       The following reminder will be triggered on Thursdays and Fridays,  but
       will only be queued on Fridays:

            REM Fri ++1 AT 13:00 MSG Lunch at 1pm Friday.

       The  tdelta  and  trepeat have the same form as a repeat and delta, but
       are specified in minutes.  For example, this reminder will be triggered
       at 12:00pm as well as 45 minutes before:

            REM AT 12:00 +45 MSG Example

       The  following  will be issued starting at 10:45, every half hour until
       11:45, and again at noon.

            REM AT 12:00 +75 *30 MSG Example2

       The "+75" means that the reminder is issued starting 75 minutes  before
       noon; in other words, at 10:45.  The *30 specifies that the reminder is
       subsequently to be issued every 30 minutes.  Note that the reminder  is
       always  issued  at  the  specified  time,  even  if the tdelta is not a
       multiple of the trepeat.  So the above example is  issued  at  10:45am,
       11:15am,  11:45am,  and  12:00pm.  Note that in the time specification,
       there is no distinction between the "+" and "++" forms of tdelta.

       Normally, Remind  will  issue  timed  reminders  as  it  processes  the
       reminder script, as well as queuing them for later.  If you do not want
       Remind to issue the reminders when processing the script, but  only  to
       queue  them  for  later, use the -a command-line option.  If you do not
       want reminders to be queued for later, use the -q command-line  option.

       Normally, Remind forks a background process to handle queued reminders.
       If you want Remind to remain in the foreground, use the -f command-line
       option.   This  is  useful, for example, in .xinitrc scripts, where you
       can use the command:

            remind -fa myreminders &

       This ensures that when  you  exit  X-Windows,  the  Remind  process  is
       killed.

       WARNING ABOUT TIMED REMINDERS

       Note:  If you use user-defined functions or variables (described later)
       in the bodies of timed reminders, then when  the  timed  reminders  are
       activated,  the  variables and functions have the definitions that were
       in effect at the end of the reminder script.  These definitions may not
       necessarily  be  those that were in effect at the time the reminder was
       queued.

       THE SCHED AND WARN KEYWORDS

       The SCHED keyword allows more precise control over  the  triggering  of
       timed  reminders,  and the WARN keyword allows precise control over the
       advance triggering of all types of reminders.  However, discussion must
       be  deferred  until  after  expressions  and user-defined functions are
       explained.  See the subsection "Precise Scheduling" further on.

       TAG AND DURATION

       The TAG keyword lets you "tag" certain  reminders.   This  facility  is
       used  by  certain  back-ends  or  systems  built around Remind, such as
       TkRemind.  These back-ends have specific rules about tags;  you  should
       not  use  the  TAG keyword yourself, or your script will interact badly
       with back-ends.

       The TAG keyword is followed by a tag consisting of up to 48 characters.

       If  you  supply the -y option to Remind, then any reminder that lacks a
       TAG will have one synthesized.  The synthesized  tag  consists  of  the
       characters  "__syn__" followed by the hexadecimal representation of the
       MD5 sum of the REM command line.  This lets  you  give  a  more-or-less
       unique identifier to each distinct REM command.

       The DURATION keyword makes sense only for timed reminders; it specifies
       the duration of an event.  Currently, this is not used, but it  may  be
       used  in future by back-ends or scheduling systems built around Remind.
       For example, if you have a 90-minute meeting starting  at  1:00pm,  you
       could use:

            REM 5 March 1999 AT 13:00 DURATION 1:30 MSG Meeting

       Note that duration is specified in hours and minutes.

THE SUBSTITUTION FILTER

       Before  being  processed, the body of a REM command is passed through a
       substitution filter.  The filter scans for sequences "%x" (where "x" is
       any  letter and certain other characters) and performs substitutions as
       shown below.  (All dates refer to the trigger date of the reminder.)

       %a     is replaced with "on weekday, day month, year"
              For example, consider the reminder:

              REM 18 Oct 1990 +4 MSG Meeting with Bob %a.

              On 16  October  1990,  it  would  print  "Meeting  with  Bob  on
              Thursday, 18 October, 1990."

              On  17 October 1990, it would print "Meeting with Bob tomorrow."

              On 18 October 1990, it would print "Meeting with Bob today."

       %b     is replaced with "in diff day’s time" where diff is  the  actual
              number  of  days  between the current date and the trigger date.
              (OMITs have no effect.)
              For example, consider:

              REM 18 Oct 1990 +4 MSG Meeting with Bob %b.

              On 16 October 1990, it would print "Meeting with Bob in 2  days’
              time."

              On  17 October 1990, it would print "Meeting with Bob tomorrow."

              On 18 October 1990, it would print "Meeting with Bob today."

       %c     is replaced with "on weekday"
              Example: REM 18 Oct 1990 +4 MSG Meeting with Bob %c.

              On 16  October  1990,  it  would  print  "Meeting  with  Bob  on
              Thursday."

              On  17 October 1990, it would print "Meeting with Bob tomorrow."

              On 18 October 1990, it would print "Meeting with Bob today."

       %d     is replaced with "day", the day of the month.

       %e     is replaced with "on dd-mm-yyyy"

       %f     is replaced with "on mm-dd-yyyy"

       %g     is replaced with "on weekday, day month"

       %h     is replaced with "on dd-mm"

       %i     is replaced with "on mm-dd"

       %j     is replaced with "on weekday, month  day-th,  year"   This  form
              appends  the  characters  "st", "nd", "rd" or "th" to the day of
              the month, as appropriate.

       %k     is replaced with "on weekday, month day-th"

       %l     is replaced with "on yyyy-mm-dd"

       %m     is replaced with "month", the name of the month.

       %n     is replaced with the number (1 to 12) of the month.

       %o     is replaced with " (today)" if and only if  the  current  system
              date is the same as the date being used by Remind as the current
              date.  Recall that you can specify a date for Remind to  use  on
              the  command line.  This substitution is not generally useful in
              a REM command, but is useful in a  BANNER  command.   (See  "The
              BANNER Command.")

       %p     is  replaced  with  "s" if the diff between the current date and
              the trigger date is not  1.   You  can  use  this  to  construct
              reminders like:
              REM 1 Jan +4 MSG %x day%p to go before New Year!

       %q     is  replaced  with "’s" if the diff between the trigger date and
              the current date is 1.  Otherwise,  it  is  replaced  with  "s’"
              This can be used as follows:
              REM 1 Jan +4 MSG New Year in %x day%q time!

       %r     is  replaced  with the day of the month (01 to 31) padded with a
              leading zero if needed to pad to two digits.

       %s     is replaced with "st", "nd", "rd" or "th" depending on  the  day
              of the month.

       %t     is  replaced  with  the number of the month (01 to 12) padded to
              two digits with a leading zero.

       %u     is replaced with "on  weekday,  day-th  month,  year"   This  is
              similar  to  %a except that "st", "nd", "rd" or "th" is added to
              the day as appropriate.

       %v     is replaced with "on weekday, day-th month"

       %w     is replaced with "weekday", the name of the day of the week.

       %x     is replaced with the diff  between  the  current  date  and  the
              trigger  date.  The diff is defined as the actual number of days
              between these two dates; OMITs are not  counted.   (Strict  date
              subtraction is performed.)

       %y     is replaced with "year", the year of the trigger date.

       %z     is replaced with "yy", the last two digits of the year.

       %_     (percent-underscore)  is  replaced  with a newline.  You can use
              this to achieve multi-line reminders.

       %1     is replaced with "now", "m minutes from now", "m  minutes  ago",
              "h  hours  from now", "h hours ago", "h hours and m minutes from
              now" or "h hours and m minutes ago", as appropriate for a  timed
              reminder.   Note  that  unless  you specify the -a option, timed
              reminders will be triggered like normal reminders,  and  thus  a
              timed   reminder  that  occurred  earlier  in  the  day  may  be
              triggered.  This causes the need for the "...ago" forms.

       %2     is replaced with "at hh:mmam" or "..pm" depending on the AT time
              of the reminder.

       %3     is replaced with "at hh:mm" in 24-hour format.

       %4     is  replaced with "mm" where mm is the number of minutes between
              "now" and the time specified by AT.  If the AT time  is  earlier
              than the current time, then the result is negative.

       %5     is  replaced  with  "ma"  where  ma is the absolute value of the
              number produced by %4.

       %6     is  replaced  with  "ago"  or  "from  now",  depending  on   the
              relationship between the AT time and the current time.

       %7     is replaced with the number of hours between the AT time and the
              current time.  It is always non-negative.

       %8     is replaced with the number of minutes between the AT  time  and
              the current time, after the hours (%7) have been subtracted out.
              This is a number ranging from 0 to 59.

       %9     is replaced with "s" if the value produced by %8 is not 1.

       %0     is replaced with "s" if the value produced by %7 is not 1.

       %!     is replaced with "is" if the current time is before the AT time,
              or "was" if it is after.

       %@     is similar to %2 but displays the current time.

       %#     is similar to %3 but displays the current time.

       %"     (percent-doublequote - ") is removed.  This sequence is not used
              by the substitution filter, but is used  to  tell  Remind  which
              text to include in a calendar entry when the -c, -s or -p option
              is chosen.  See "Calendar Mode"

       Notes:

       o      Remind normally prints a blank line after each reminder; if  the
              last  character  of  the body is "%", the blank line will not be
              printed.

       o      Substitutions a, b, c, e, f, g, h, i, j, k, l, u and v  all  are
              replaced  with  "today"  if  the current date equals the trigger
              date, or "tomorrow" if the trigger date is  one  day  after  the
              current  date.   Thus,  they  are  not the same as substitutions
              built up from the simpler %w, %y, etc.  sequences.

       o      Any of the substitutions dealing with time (0 through 9 and ’!’)
              produce  undefined  results  if used in a reminder that does not
              have an AT keyword.  Also, if a reminder has a delta and may  be
              triggered  on  several  days,  the time substitutions ignore the
              date.  Thus, the %1 substitution may report that a meeting is in
              15  minutes,  for  example, even though it may only be in 2 days
              time, because  a  delta  has  triggered  the  reminder.   It  is
              recommended  that  you  use the time substitutions only in timed
              reminders with no delta that are designed to be queued for timed
              activation.

       o      Capital  letters  can  be  used in the substitution sequence, in
              which case the first character  of  the  substituted  string  is
              capitalized (if it is normally a lower-case letter.)

       o      All other characters following a "%" sign are simply copied.  In
              particular, to get a "%" sign out, use "%%"  in  the  body.   To
              start  the  body  of  a  reminder  with a space, use "% ", since
              Remind normally scans for the first non-space character after  a
              MSG, CAL or RUN token.

THE OMIT COMMAND

       In addition to being a keyword in the REM command, OMIT is a command in
       its own right.  Its syntax is:

              OMIT day month [year]

       The OMIT command is used  to  "globally"  omit  certain  days  (usually
       holidays).   These globally-omitted days are skipped by the "-" and "+"
       forms of back and delta.  Some examples:

            OMIT 1 Jan
            OMIT 7 Sep 1992

       The first example specifies a holiday that occurs on the same date each
       year  -  New  Year’s  Day.  The second example specifies a holiday that
       changes each year - Labour Day.  For these types of holidays, you  must
       create  an  OMIT  command for each year.  (Later, in the description of
       expressions and some of the more advanced features of Remind, you  will
       see how to automate this for some cases.)

       For convenience, you can use a delta and MSG or RUN keyword in the OMIT
       command.  The following sequences are exactly equivalent:

            OMIT 1 Jan
            REM 1 Jan +4 MSG New year’s day is %b!

            and

            OMIT 1 Jan +4 MSG New year’s day is %b!

       THE BEFORE, AFTER AND SKIP KEYWORDS

       Normally, days that are omitted, whether by a global  OMIT  command  or
       the  local OMIT keyword in a REM statement, only affect the counting of
       the -back or the +delta.  For example, suppose you have a meeting every
       Wednesday.  Suppose, too, that you have indicated 11 Nov as a holiday:

            OMIT 11 Nov +4 MSG Remembrance Day
            REM Wed +1 MSG Code meeting %b.

       The  above  sequence  will  issue  a  reminder  about  a meeting for 11
       November 1992, which is  a  Wednesday.   This  is  probably  incorrect.
       There are three options:

       BEFORE This  keyword  moves  the  reminder  to before any omitted days.
              Thus, in the above  example,  use  of  BEFORE  would  cause  the
              meeting reminder to be triggered on Tuesday, 10 November 1992.

       AFTER  This  keyword  moves the reminder to after any omitted days.  In
              the above example, the meeting reminder would  be  triggered  on
              Thursday, 12 November 1992.

       SKIP   This keyword causes the reminder to be skipped completely on any
              omitted days.  Thus, in the above example,  the  reminder  would
              not  be  triggered  on  11  November 1992.  However, it would be
              triggered as usual on the following Wednesday, 18 November 1992.

       The  BEFORE  and  AFTER keywords move the trigger date of a reminder to
       before or after a block of omitted  days,  respectively.   Suppose  you
       normally  run  a backup on the first day of the month.  However, if the
       first day of the month is a weekend or holiday, you run the  backup  on
       the first working day following the weekend or holiday.  You could use:

            REM 1 OMIT Sat Sun AFTER RUN do_backup

       Let’s examine how the trigger date is computed.  The  1  specifies  the
       first  day  of  the  month.   The  local  OMIT keyword causes the AFTER
       keyword to move the reminder forward past weekends.  Finally, the AFTER
       keyword  will  keep moving the reminder forward until it has passed any
       holidays specified with global OMIT commands.

THE INCLUDE COMMAND

       Remind allows you to include  other  files  in  your  reminder  script,
       similar  to  the  C preprocessor #include directive.  For example, your
       system administrator may maintain a file  of  holidays  or  system-wide
       reminders.  You can include these in your reminder script as follows:

            INCLUDE /usr/share/remind/holidays
            INCLUDE /usr/share/remind/reminders

       (The  actual  pathnames  vary  from  system to system - ask your system
       administrator.)

       INCLUDE files can be nested up to a depth of 8.

       If you specify a filename of "-" in the INCLUDE  command,  Remind  will
       begin reading from standard input.

       If you specify a directory as the argument to INCLDUE, then Remind will
       process all files in  that  directory  that  match  the  shell  patterm
       "*.rem".   The  files  are  processed  in  sorted order; the sort order
       matches that used by the shell when it expands "*.rem".

THE RUN COMMAND

       If you include other files in your reminder script, you may not  always
       entirely  trust the contents of the other files.  For example, they may
       contain RUN-type reminders that could be used to access your  files  or
       perform  undesired actions.  The RUN command can restrict this:  If you
       include the command RUN OFF in  your  top-level  reminder  script,  any
       reminder  or expression that would normally execute a system command is
       disabled.  RUN ON will re-enable  the  execution  of  system  commands.
       Note  that  the  RUN  ON  command  can  only  be used in your top-level
       reminder script; it will not work in any files accessed by the  INCLUDE
       command.   This is to protect you from someone placing a RUN ON command
       in an included file.  However, the RUN OFF command can be used  at  top
       level or in an included file.

       If  you  run Remind with the -r command-line option, RUN-type reminders
       and the shell() function  will  be  disabled,  regardless  of  any  RUN
       commands  in  the  reminder script.  However, any command supplied with
       the -k option will still be executed.

       One use of the RUN command is to provide  a  secure  interface  between
       Remind  and the Elm mail system.  The Elm system can automatically scan
       incoming mail for reminder or calendar entries, and place them in  your
       calendar  file.   To  use  this  feature,  you  should set the calendar
       filename option under Elm to be something like  "~/.reminders.in",  not
       your main reminder file!  This is so that any RUN ON commands mailed to
       you can never be activated.

       Then, you can use the Elm scan message for calendar entries command  to
       place  reminders  prefaced  by  "->"  into .reminders.in.  In your main
       .reminders file, include the following lines:

            RUN OFF   # Disable RUN
            INCLUDE .reminders.in
            RUN ON    # Re-enable RUN

       In addition, Remind contains a few other security  features.   It  will
       not read a file that is group- or world-writable.  It will not run set-
       uid.  If it reads a file you don’t own, it will  disable  RUN  and  the
       shell()  function.   And  if it is run as root, it will only read files
       owned by root.

THE BANNER COMMAND

       When Remind first issues a reminder, it prints a message like this:

            Reminders for Friday, 30th October, 1992 (today):

       (The banner is not printed if any of the calendar-producing options  is
       used, or if the -k option is used.)

       The BANNER command lets you change the format.  It should appear before
       any REM commands.  The format is:

              BANNER format

       The format is similar to the body of  a  REM  command.   It  is  passed
       through  the  substitution  filter,  with  an  implicit  trigger of the
       current system date.  Thus, the default banner is equivalent to:

            BANNER Reminders for %w, %d%s %m, %y%o:

       You can disable the banner completely with BANNER %.  Or you can create
       a custom banner:

            BANNER Hi - here are your reminders for %y-%t-%r:

CONTROLLING THE OMIT CONTEXT

       Sometimes,  it is necessary to temporarily change the global OMITs that
       are in force for a few reminders.  Three commands allow you to do this:

       PUSH-OMIT-CONTEXT
              This  command  saves  the  current  global  OMITs on an internal
              stack.

       CLEAR-OMIT-CONTEXT
              This command clears all of the global OMITs,  starting  you  off
              with a "clean slate."

       POP-OMIT-CONTEXT
              This  command  restores  the global OMITs that were saved by the
              most recent PUSH-OMIT-CONTEXT.

       For example, suppose you have a block of reminders that require a clear
       OMIT  context,  and that they also introduce unwanted global OMITs that
       could interfere with later reminders.   You  could  use  the  following
       fragment:

            PUSH-OMIT-CONTEXT   # Save the current context
            CLEAR-OMIT-CONTEXT  # Clean the slate
            # Block of reminders goes here
            POP-OMIT-CONTEXT    # Restore the saved omit context

EXPRESSIONS

       In  certain  contexts,  to  be  described  later,  Remind  will  accept
       expressions for evaluation.  Remind expressions resemble C expressions,
       but operate on different types of objects.

       DATA TYPES

       Remind expressions operate on five types of objects:

       INT    The  INT data type consists of the integers representable in one
              machine word.  The INT data type  corresponds  to  the  C  "int"
              type.

       STRING The  STRING  data type consists of strings of characters.  It is
              somewhat comparable to a C character  array,  but  more  closely
              resembles the string type in BASIC.

       TIME   The  TIME data type consists of times of the day.  The TIME data
              type is internally stored as an integer representing the  number
              of minutes since midnight.

       DATE   The  DATE  data  type  consists  of  dates (later than 1 January
              1990.)  Internally, DATE objects are stored  as  the  number  of
              days since 1 January 1990.

       DATETIME
              The  DATETIME  data  type  consists of a date and time together.
              Internally, DATETIME objects are stored as the number of minutes
              since  midnight,  1  January  1990.  You can think of a DATETIME
              object as being the combination of DATE and TIME parts.

       CONSTANTS

       The following examples illustrate constants in Remind expressions:

       INT constants
              12, 36, -10, 0, 1209

       STRING constants
              "Hello there", "This is a test", "\n\gosd\w", ""

              Note that the empty  string  is  represented  by  "",  and  that
              backslashes  in  a  string  are not interpreted specially, as in
              they are in C.

       TIME constants
              12:33, 0:01, 14:15, 16:42, 12.16, 13.00, 1.11

              Note that TIME constants are written in 24-hour format.   Either
              the period or colon can be used to separate the minutes from the
              hours.  However, Remind will  consistently  output  times  using
              only  one  separator character.  (The output separator character
              is chosen at compile-time.)

       DATE constants
              DATE constants are expressed as  ’yyyy/mm/dd’  or  ’yyyy-mm-dd’,
              and the single quotes must be supplied.  This distinguishes date
              constants from division or subtraction of integers.  Examples:

              ´1993/02/22’, ’1992-12-25’, ’1999/01/01’

              Note that DATE values are printed without the quotes.   Although
              either ’-’ or ’/’ is accepted as a date separator on input, when
              dates are printed, only one will be used.  The choice of whether
              to  use  ’-’  or  ’/’  is  made at compile-time.  Note also that
              versions of Remind  prior  to  03.00.01  did  not  support  date
              constants.   In  those versions, you must create dates using the
              date() function.  Also,  versions  prior  to  03.00.02  did  not
              support the ’-’ date separator.

       DATETIME constants
              DATETIME  constants  are  expressed  similarly to DATE constants
              with the addition of an "@HH:MM" part.  For example:

              ´2008-04-05@23:11’, ’1999/02/03@14:06’, ’2001-04-07@08:30’

              DATETIME values are printed without  the  quotes.   Notes  about
              date  and  time separator characters for DATE and TIME constants
              apply also to DATETIME constants.

       OPERATORS

       Remind has the following operators.  Operators on the  same  line  have
       equal  precedence, while operators on lower lines have lower precedence
       than those on higher lines.  The operators approximately correspond  to
       C operators.

            !  -     (unary logical negation and arithmetic negation)
            *  /  %
            +  -
            <  <=  >  >=
            ==  !=
            &&
            ||

       DESCRIPTION OF OPERATORS

       !      Logical  negation.   Can  be  applied  to  an  INT type.  If the
              operand is non-zero, returns zero.  Otherwise, returns 1.

       -      Unary minus.  Can be applied to an INT.  Returns the negative of
              the operand.

       *      Multiplication.  Returns the product of two INTs.

       /      Integer  division.  Returns the quotient of two INTs, discarding
              the remainder.

       %      Modulus.   Returns  the  remainder  upon  dividing  one  INT  by
              another.

       +      Has several uses.  These are:

              INT + INT - returns the sum of two INTs.

              INT + TIME or TIME + INT - returns a TIME obtained by adding INT
              minutes to the original TIME.

              INT + DATE or DATE + INT - returns a DATE obtained by adding INT
              days to the original DATE.

              INT  +  DATETIME or DATETIME + INT - returns a DATETIME obtained
              by adding INT minutes to the original DATETIME.

              STRING + STRING - returns a STRING that is the concatenation  of
              the two original STRINGs.

              STRING + anything or anything + STRING - converts the non-STRING
              argument to a STRING, and then performs concatenation.  See  the
              coerce() function.

       -      Has several uses.  These are:

              INT - INT - returns the difference of two INTs.

              DATE - DATE - returns (as an INT) the difference in days between
              two DATEs.

              TIME - TIME - returns (as an  INT)  the  difference  in  minutes
              between two TIMEs.

              DATETIME  -  DATETIME  -  returns  (as an INT) the difference in
              minutes between two DATETIMEs.

              DATE - INT - returns a DATE that is INT days  earlier  than  the
              original DATE.

              TIME - INT - returns a TIME that is INT minutes earlier than the
              original TIME.

              DATETIME - INT - returns a DATETIME that is INT minutes  earlier
              than the original DATETIME.

       <, <=, >, and >=
              These  are  the comparison operators.  They can take operands of
              any type, but both operands must  be  of  the  same  type.   The
              comparison operators return 1 if the comparison is true, or 0 if
              it is false.  Note that string comparison is done following  the
              lexical  ordering  of  characters on your system, and that upper
              and lower case are distinct for these operators.

       ==, != == tests for equality, returning 1 if its  operands  are  equal,
              and 0 if they are not.  != tests for inequality.

              If  the  operands  are not of the same type, == returns 0 and !=
              returns 1.  Again, string comparisons are case-sensitive.

       &&     This is the logical AND operator.  Both of its operands must  be
              of  type INT.  It returns 1 if both operands are non-zero, and 0
              otherwise.

       ||     This is the logical OR operator.  Both of its operands  must  be
              of  type INT.  It returns 1 if either operand is non-zero, and 0
              otherwise.

       NOTES

       Operators of equal precedence are always evaluated from left to  right,
       except where parentheses dictate otherwise.  This is important, because
       the enhanced "+" operator is not necessarily associative.  For example:

            1 + 2 + "string" + 3 + 4  yields "3string34"
            1 + (2 + "string") + (3 + 4)  yields "12string7"
            12:59 + 1 + "test"  yields "13:00test"
            12:59 + (1 + "test")  yields "12:591test"

       The  logical  operators  are  not so-called short-circuit operators, as
       they  are  in  C.   Both  operands  are  always  evaluated.   Thus,  an
       expression such as:

            (f!=0) && (100/f <= 3)

       will cause an error if f is zero.

       VARIABLES

       Remind  allows  you  to assign values to variables.  The SET command is
       used as follows:

       SET var expr

       Var is the name of  a  variable.   It  must  start  with  a  letter  or
       underscore,  and consist only of letters, digits and underscores.  Only
       the first 12 characters of a variable name are  significant.   Variable
       names  are  not  case  sensitive;  thus, "Afoo" and "afOo" are the same
       variable.  Examples:

            SET a 10 + (9*8)
            SET b "This is a test"
            SET mydir getenv("HOME")
            SET time 12:15
            SET date today()

       Note that variables themselves have no type.  They take on the type  of
       whatever you store in them.

       To delete a variable, use the UNSET command:

       UNSET var [var...]

       For example, to delete all the variables declared above, use:

            UNSET a b mydir time date

       SYSTEM VARIABLES

       In  addition  to the regular user variables, Remind has several "system
       variables" that are used to query or control  the  operating  state  of
       Remind.   System variables are available starting from version 03.00.07
       of Remind.

       All system variables begin with a dollar sign ’$’.  They can be used in
       SET commands and expressions just as regular variables can.  All system
       variables always hold values of a specified type.   In  addition,  some
       system  variables  cannot be modified, and you cannot create new system
       variables.  System variables can be initialized  on  the  command  line
       with  the -i option, but you may need to quote them to avoid having the
       shell interpret the dollar sign.  System variable names are  not  case-
       sensitive.

       The  following  system variables are defined.  Those marked "read-only"
       cannot be changed with the SET  command.   All  system  variables  hold
       values of type INT, unless otherwise specified.

       $CalcUTC
              If  1  (the  default),  then  Remind uses C library functions to
              calculate the number of minutes between local and Universal Time
              Coordinated.   This affects astronomical calculations (sunrise()
              for example.)  If 0, then you must supply the number of  minutes
              between local and Universal Time Coordinated in the $MinsFromUTC
              system variable.

       $CalMode (read-only)
              If non-zero, then the -c option  was  supplied  on  the  command
              line.

       $Daemon (read-only)
              If  the  daemon  mode  -z  was  invoked,  contains the number of
              minutes  between  wakeups.   If  not  running  in  daemon  mode,
              contains 0.  For the MS-DOS version, always contains 0.

       $DateSep
              This  variable  can  be  set  only  to "/" or "-".  It holds the
              character used to separate portions of a date when Remind prints
              a DATE or DATETIME value.

       $DefaultPrio
              The  default  priority  assigned to reminders without a PRIORITY
              clause.  You can set this as required to adjust  the  priorities
              of  blocks  of  reminders  without having to type priorities for
              individual reminders.  At startup, $DefaultPrio is set to  5000;
              it can range from 0 to 9999.

       $DontFork (read-only)
              If  non-zero,  then  the  -c  option was supplied on the command
              line.  For the MS-DOS version, always contains 1.

       $DontTrigAts (read-only)
              If non-zero, then the -a option  was  supplied  on  the  command
              line.  For the MS-DOS version, always contains 0.

       $DontQueue (read-only)
              If  non-zero,  then  the  -q  option was supplied on the command
              line.  For the MS-DOS version, always contains 1.

       $EndSent (STRING type)
              Contains a list of characters that  end  a  sentence.   The  MSF
              keyword  inserts  two spaces after these characters.  Initially,
              $EndSent is set to ".!?" (period, exclamation mark, and question
              mark.)

       $EndSentIg (STRING type)
              Contains  a  list  of characters that should be ignored when MSF
              decides whether or not to place two  spaces  after  a  sentence.
              Initially,  is  set  to "’>)]}"+CHAR(34) (single-quote, greater-
              than, right parenthesis, right bracket, right brace, and double-
              quote.)

              For example, the default values work as follows:

                   MSF He said, "Huh! (Two spaces will follow this.)"  Yup.

              because  the  final  parenthesis  and quote are ignored (for the
              purposes of spacing) when they follow a period.

       $FirstIndent
              The number of spaces by which to indent the first line of a MSF-
              type reminder.  The default is 0.

       $FoldYear
              The  standard Unix library functions may have difficulty dealing
              with dates later than 2037.  If this variable is set to 1,  then
              the  UTC  calculations  "fold back" years later than 2037 before
              using the Unix library functions.   For  example,  to  find  out
              whether or not daylight savings time is in effect in June, 2077,
              the year is "folded back" to 2010, because both years begin on a
              Monday,  and  both  are  non-leapyears.   The rules for daylight
              savings time are thus presumed to be identical for  both  years,
              and  the  Unix  library  functions can handle 2010.  By default,
              this variable is 0.  Set it to 1 if the  sun  or  UTC  functions
              misbehave for years greater than 2037.

       $FormWidth
              The  maximum  width of each line of text for formatting MSF-type
              reminders.  The default is 72.  If an MSF-type reminder contains
              a word too long to fit in this width, it will not be truncated -
              the width limit will be ignored.

       $HushMode (read-only)
              If non-zero, then the -h option  was  supplied  on  the  command
              line.

       $IgnoreOnce (read-only)
              If  non-zero,  then  the  -o  option was supplied on the command
              line, or a date different from today’s true date  was  supplied.
              If non-zero, then ONCE directives will be ignored.

       $InfDelta (read-only)
              If  non-zero,  then  the  -t  option was supplied on the command
              line.

       $LatDeg, $LatMin, $LatSec
              These specify the latitude of your location.  $LatDeg can  range
              from  -90  to  90,  and  the  others  from  -59 to 59.  Northern
              latitudes  are  positive;  southern  ones  are  negative.    For
              southern latitudes, all three components should be negative.

       $Location (STRING type)
              This  is  a  string specifying the name of your location.  It is
              usually the name of your  town  or  city.   It  can  be  set  to
              whatever  you  like,  but good style indicates that it should be
              kept  consistent  with  the  latitude   and   longitude   system
              variables.

       $LongDeg, $LongMin, $LongSec
              These  specify  the  longitude  of  your location.  $LongDeg can
              range from  -180  to  180.   Western  longitudes  are  positive;
              eastern ones are negative.

              The  latitude  and  longitude  information  is  required for the
              functions  sunrise()  and  sunset().   Default  values  can   be
              compiled  into  Remind, or you can SET the correct values at the
              start of your reminder scripts.

       $MaxSatIter
              The  maximum  number  of  iterations  for  the  SATISFY   clause
              (described later.)  Must be at least 10.

       $MinsFromUTC
              The  number  of  minutes  between Universal Time Coordinated and
              local time.  If $CalcUTC is non-zero, this  is  calculated  upon
              startup  of  Remind.  Otherwise, you must set it explicitly.  If
              $CalcUTC is zero, then $MinsFromUTC is used in the  astronomical
              calculations.   You  must  adjust  it  for daylight savings time
              yourself.  Also, if you want to  initialize  $MinsFromUTC  using
              the -i command-line option, you must also set $CalcUTC to 0 with
              the -i option.

       $NextMode (read-only)
              If non-zero, then the -n option  was  supplied  on  the  command
              line.

       $NumQueued (read-only)
              Contains  the  number  of reminders queued so far for background
              timed triggering.  For MS-DOS, always returns 0.

       $NumTrig (read-only)
              Contains the number of reminders triggered for the current date.
              One  use  for  this variable is as follows:  Suppose you wish to
              shade in the box of a PostScript calendar whenever a holiday  is
              triggered.   You  could  save the value of $NumTrig in a regular
              variable prior to executing a block of  holiday  reminders.   If
              the  value  of  $NumTrig after the holiday block is greater than
              the saved value, then at least one holiday  was  triggered,  and
              you  can execute the command to shade in the calendar box.  (See
              the section "Calendar Mode".)

              Note that $NumTrig is affected only by REM commands; triggers in
              IFTRIG commands do not affect it.

       $PrefixLineNo (read-only)
              If  non-zero,  then  the  -l  option was supplied on the command
              line.

       $PSCal (read-only)
              If non-zero, then the -p option  was  supplied  on  the  command
              line.

       $RunOff (read-only)
              If non-zero, the RUN directives are disabled.

       $SimpleCal (read-only)
              Set  to  a non-zero value if either of the -p or -s command-line
              options was supplied.

       $SortByDate (read-only)
              Set to 0 if no -g option is  used,  1  if  sorting  by  date  in
              ascending order, or 2 if sorting by date in descending order.

       $SortByPrio (read-only)
              Set  to  0  if no -g option is used, 1 if sorting by priority in
              ascending order, or 2  if  sorting  by  priority  in  descending
              order.

       $SortByTime (read-only)
              Set  to  0  if  no  -g  option  is used, 1 if sorting by time in
              ascending order, or 2 if sorting by time in descending order.

       $SubsIndent
              The number of spaces by which all lines (except the first) of an
              MSF-type reminder should be indented.  The default is 0.

       Note:   If  any of the calendar modes are in effect, then the values of
       $Daemon, $DontFork, $DontTrigAts, $DontQueue,  $HushMode,  $IgnoreOnce,
       $InfDelta, and $NextMode are not meaningful.

       $TimeSep
              This  variable  can  be  set  only  to ":" or ".".  It holds the
              character used to separate portions of a time when Remind prints
              a TIME or DATETIME value.

       BUILT-IN FUNCTIONS

       Remind has a plethora of built-in functions.  The syntax for a function
       call is the same as in  C  -  the  function  name,  followed  a  comma-
       separated  list  of  arguments  in parentheses.  Function names are not
       case-sensitive.  If a function takes no arguments, it must be  followed
       by "()" in the function call.  Otherwise, Remind will interpret it as a
       variable name, and probably not work correctly.

       In the descriptions below, short forms are used  to  denote  acceptable
       types  for  the  arguments.   The characters "i", "s", "d", "t" and "q"
       denote INT, STRING, DATE, TIME and  DATETIME  arguments,  respectively.
       If  an  argument  can  be  one  of  several  types,  the characters are
       concatenated.  For example, "di_arg" denotes an argument that can be  a
       DATE  or  an INT.  "x_arg" denotes an argument that can be of any type.
       The type of the argument is followed by an underscore and an identifier
       naming the argument.

       The built-in functions are:

       abs(i_num)
              Returns the absolute value of num.

       access(s_file, si_mode)
              Tests  the  access permissions for the file file.  Mode can be a
              string, containing a mix of the characters "rwx" for read, write
              and  execute  permission  testing.  Alternatively, mode can be a
              number as described in the  UNIX  access(2)  system  call.   The
              function  returns  0  if  the  file  can  be  accessed  with the
              specified mode, and -1 otherwise.

       args(s_fname)
              Returns the number of arguments  expected  by  the  user-defined
              function  fname,  or -1 if no such user-defined function exists.
              Note that this function examines  only  user-defined  functions,
              not built-in functions.  Its main use is to determine whether or
              not  a  particular  user-defined  function  has   been   defined
              previously.   The  args() function is available only in versions
              of Remind from 03.00.04 and up.

       asc(s_string)
              Returns an INT that is the ASCII code of the first character  in
              string.  As a special case, asc("") returns 0.

       baseyr()
              Returns  the "base year" that was compiled into Remind (normally
              1990.)  All dates are stored internally as the  number  of  days
              since 1 January of baseyr().

       char(i_i1 [,i_i2...])
              This  function can take any number of INT arguments.  It returns
              a  STRING  consisting  of  the  characters  specified   by   the
              arguments.   Note  that  none  of the arguments can be 0, unless
              there is only one argument.  As a special case, char(0)  returns
              "".

              Note that because Remind does not support escaping of characters
              in strings, the only way to get a double-quote in a string is to
              use char(34).

       choose(i_index, x_arg1 [,x_arg2...])
              Choose  must  take at least two arguments, the first of which is
              an INT.  If index is n, then  the  nth  subsequent  argument  is
              returned.   If  index is less than 1, then arg1 is returned.  If
              index is greater than the number of subsequent  arguments,  then
              the last argument is returned.  Examples:

                 choose(0, "foo", 1:13, 1000) returns "foo"
                 choose(1, "foo", 1:13, 1000) returns "foo"
                 choose(2, "foo", 1:13, 1000) returns 1:13
                 choose(3, "foo", 1:13, 1000) returns 1000
                 choose(4, "foo", 1:13, 1000) returns 1000
              Note that all arguments to choose() are always evaluated.

       coerce(s_type, x_arg)
              This  function  converts  arg  to  the  specified  type, if such
              conversion is possible.  Type must be one  of  "INT",  "STRING",
              "DATE", "TIME" or "DATETIME" (case-insensitive).  The conversion
              rules are as follows:

              If arg  is  already  of  the  type  specified,  it  is  returned
              unchanged.

              If  type  is  "STRING",  then  arg  is  converted  to  a  string
              consisting of its printed representation.

              If type is "DATE", then an INT arg is converted by  interpreting
              it as the number of days since 1 January baseyr().  A STRING arg
              is converted by attempting to read it as if it  were  a  printed
              date.   A  DATETIME  is converted to a date by dropping the time
              component.  A TIME arg cannot be converted to a date.

              If type is "TIME", then an INT arg is converted by  interpreting
              it  as  the  number  of minutes since midnight.  A STRING arg is
              converted by attempting to read it as if it were a printed time.
              A  DATETIME  is  converted  to  a  time  by  dropping  the  date
              component.  A DATE arg cannot be converted to a time.

              If  type  is  "DATETIME",  then  an  INT  arg  is  converted  by
              interpreting  it  as  the  number  of  minutes since midnight, 1
              January baseyr().  A STRING is converted by attempting  to  read
              it  as  if  it  were  a printed datetime.  Other types cannot be
              converted to a datetime.

              If type is "INT", then DATE, TIME  and  DATETIME  arguments  are
              converted  using  the  reverse of procedures described above.  A
              STRING arg is converted by parsing it as an integer.

       current()
              Returns the current date and time as a  DATETIME  object.   This
              may  be  the  actual  date and time, or may be the date and time
              supplied on the command line.

       date(i_y, i_m, i_d)
              The date() function returns a DATE object with the  year,  month
              and day components specified by y, m and d.

       datetime(args)
              The  datetime()  function  can  take  anywhere  from two to five
              arguments.  It always returns  a  DATETIME  generated  from  its
              arguments.

              If  you  supply  two arguments, the first must be a DATE and the
              second a TIME.

              If you supply three arguments, the first must be a DATE and  the
              second  and  third must be INTs.  The second and third arguments
              are interpreted as hours and minutes and converted to a TIME.

              If you supply four arguments, the  first  three  must  be  INTs,
              interpreted  as  the  year,  month and day.  The fourth argument
              must be a TIME.

              Finally, if you supply five arguments, they must all be INTs and
              are interpreted as year, month, day, hour and minute.

       dawn([dq_date])
              Returns the time of "civil dawn" on the specified date.  If date
              is omitted, defaults  to  today().   If  a  datetime  object  is
              supplied, only the date component is used.

       day(dq_date)
              This  function  takes  a  DATE  or  DATETIME as an argument, and
              returns an INT that is the day-of-month component of date.

       daysinmon(i_m, i_y)
              Returns the number of days in month m (1-12) of the year y.

       defined(s_var)
              Returns 1 if the variable named by var is defined, or 0 if it is
              not.
              Note  that  defined() takes a STRING argument; thus, to check if
              variable X is defined, use:

                        defined("X")

              and not:

                        defined(X)

              The second example will attempt to evaluate X, and  will  return
              an error if it is undefined or not of type STRING.

       dosubst(s_str [,d_date [,t_time]]) or dosubst(s_str [,q_datetime])
              Returns  a  STRING that is the result of passing str through the
              substitution filter described earlier.  The parameters date  and
              time (or datetime) establish the effective trigger date and time
              used by the substitution filter.  If date and time are  omitted,
              they default to today() and now().

              Note that if str does not end with "%", a newline character will
              be added to the end of the result.  Also, calling dosubst() with
              a  date  that  is  in  the  past  (i.e., if date < today()) will
              produce undefined results.

              Dosubst() is only available starting from  version  03.00.04  of
              Remind.

       dusk([dq_date])
              Returns  the time of "civil twilight" on the specified date.  If
              date is omitted, defaults to today().

       easterdate(dqi_arg)
              If arg is an INT, then returns the date of Easter Sunday for the
              specified  year.  If arg is a DATE or DATETIME, then returns the
              date of the next Easter Sunday  on  or  after  arg.   (The  time
              component of a datetime is ignored.)

       filedate(s_filename)
              Returns the modification date of filename.  If filename does not
              exist, or its modification date is  before  the  year  baseyr(),
              then 1 January of baseyr() is returned.

       filedatetime(s_filename)
              Returns the modification date and time of filename.  If filename
              does not exist, or its modification  date  is  before  the  year
              baseyr(), then midnight, 1 January of baseyr() is returned.

       filedir()
              Returns  the  directory  that  contains  the  current file being
              processed.  It may be a relative or absolute  pathname,  but  is
              guaranteed  to  be  correct  for  use  in  an INCLUDE command as
              follows:

                 INCLUDE [filedir()]/stuff

              This includes the file "stuff" in  the  same  directory  as  the
              current file being processed.

       filename()
              Returns  (as  a  STRING)  the  name  of  the  current file being
              processed by Remind.  Inside included files, returns the name of
              the included file.

       getenv(s_envvar)
              Similar   to  the  getenv(2)  system  call.   Returns  a  string
              representing the value of the  specified  environment  variable.
              Returns  ""  if  the  environment variable is not defined.  Note
              that the names of  environment  variables  are  generally  case-
              sensitive;   thus,   getenv("HOME")   is   not   the   same   as
              getenv("home").

       hour(tq_time)
              Returns the hour component of time.

       iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default)
              If  test1  is  not  zero  or  the  null  string,  returns  arg1.
              Otherwise,  if  test2  is  not  zero or the null string, returns
              arg2, and so on.  If  all  of  the  test  arguments  are  false,
              returns  default.  Note that all arguments are always evaluated.
              This function accepts an odd number of  arguments  -  note  that
              prior  to  version  03.00.05  of Remind, it accepted 3 arguments
              only.  The  3-argument  version  of  iif()  is  compatible  with
              previous versions of Remind.

       index(s_search, s_target [,i_start)
              Returns  an  INT  that  is  the location of target in the string
              search.  The first character of a  string  is  numbered  1.   If
              target does not exist in search, then 0 is returned.

              The optional parameter start specifies the position in search at
              which to start looking for target.

       isdst([d_date [,t_time]]) or isdst(q_datetime)
              Returns a positive number if daylight savings time is in  effect
              on  the  specified  date and time.  Date defaults to today() and
              time defaults to midnight.

              Note that this function is only as reliable as  the  C  run-time
              library  functions.   It  is  available  starting  with  version
              03.00.07 of Remind.

       isleap(idq_arg)
              Returns 1 if arg is a leap year, and 0 otherwise.  Arg can be an
              INT,  DATE  or  DATETIME  object.   If  a  DATE  or  DATETIME is
              supplied, then the year component is used in the test.

       isomitted(dq_date)
              Returns 1 if date is omitted,  given  the  current  global  OMIT
              context.  Returns 0 otherwise.  (If a datetime is supplied, only
              the date part is used.)

       hebdate(i_day, s_hebmon [,idq_yrstart [,i_jahr [,i_aflag]]])
              Support for Hebrew dates - see the section "The Hebrew Calendar"

       hebday(dq_date)
              Support for Hebrew dates - see the section "The Hebrew Calendar"

       hebmon(dq_date)
              Support for Hebrew dates - see the section "The Hebrew Calendar"

       hebyear(dq_date)
              Support for Hebrew dates - see the section "The Hebrew Calendar"

       language()
              Returns a STRING naming the language supported by Remind.   (See
              "Foreign  Language  Support.") By default, Remind is compiled to
              support English messages, so this  function  returns  "English".
              For  other languages, this function will return the English name
              of the language (e.g. "German")  Note  that  language()  is  not
              available in versions of Remind prior to 03.00.02.

       lower(s_string)
              Returns  a  STRING  with  all  upper-case  characters  in string
              converted to lower-case.

       max(x_arg1 [,x_arg2...)
              Can take any number of arguments, and returns the maximum.   The
              arguments  can be of any type, but must all be of the same type.
              They are compared as with the > operator.

       min(x_arg1 [,x_arg2...)
              Can take any number of arguments, and returns the minimum.   The
              arguments  can be of any type, but must all be of the same type.
              They are compared as with the < operator.

       minsfromutc([d_date [,t_time]]) or minsfromutc(q_datetime)
              Returns the number of minutes from  Universal  Time  Coordinated
              (formerly  GMT)  to  local  time on the specified date and time.
              Date defaults to today() and  time  defaults  to  midnight.   If
              local  time  is  before UTC, the result is negative.  Otherwise,
              the result is positive.

              Note that this function is only as reliable as  the  C  run-time
              library  functions.   It  is  available  starting  with  version
              03.00.07 of Remind.

       minute(tq_time)
              Returns the minute component of time.

       mon(dqi_arg)
              If arg is of DATE or DATETIME type, returns a string that  names
              the month component of the date.  If arg is an INT from 1 to 12,
              returns a string that names the month.

       monnum(dq_date)
              Returns an INT from 1 to 12, representing the month component of
              date.

       moondate(i_phase [,d_date [,t_time]]) or moondate(i_phase, q_datetime)
              This  function  returns  the date of the first occurrence of the
              phase phase of the moon on or after date and  time.   Phase  can
              range  from 0 to 3, with 0 signifying new moon, 1 first quarter,
              2 full moon, and 3  third  quarter.   If  date  is  omitted,  it
              defaults  to  today().   If  time  is  omitted,  it  defaults to
              midnight.

              For example, the following returns the date  of  the  next  full
              moon:

                        SET fullmoon moondate(2)

       moontime(i_phase [,d_date [,t_time]]) or moontime(i_phase, q_datetime)
              This  function  returns  the time of the first occurrence of the
              phase phase of the moon on or after date and  time.   Phase  can
              range  from 0 to 3, with 0 signifying new moon, 1 first quarter,
              2 full moon, and 3  third  quarter.   If  date  is  omitted,  it
              defaults  to  today().   If  time  is  omitted,  it  defaults to
              midnight.  Moontime() is intended to be used in conjunction with
              moondate().    The   moondate()  and  moontime()  functions  are
              accurate to within a couple of minutes  of  the  times  in  "Old
              Farmer’s Almanac" for Ottawa, Ontario.

              For example, the following returns the date and time of the next
              full moon:

                        MSG Next full moon at [moontime(2)] on [moondate(2)]

       moondatetime(i_phase  [,d_date  [,t_time]])  or   moondatetime(i_phase,
       q_datetime)
              This function is similar to moondate and moontime, but returns a
              DATETIME result.

       moonphase([d_date [,t_time]]) or moonphase(q_datetime)
              This  function  returns  the phase of the moon on date and time,
              which  default  to  today()  and  midnight,  respectively.   The
              returned  value  is  an  integer from 0 to 359, representing the
              phase of the moon in degrees.  0 is a new moon, 180  is  a  full
              moon, 90 is first-quarter, etc.

       nonomitted(dq_start, dq_end [,s_wkday...])
              This  function  returns  the  number of non-omitted days between
              start and end.  If start is non-omitted,  then  it  is  counted.
              end is never counted.

              Note that end must be greater than or equal to start or an error
              is reported.  In addition to using the global OMIT context,  you
              can supply additional arguments that are names of weekdays to be
              omitted.

              For example, the following line sets a to 11 (assuming no global
              OMITs):

                   set a nonomitted(’2007-08-01’, ’2007-08-16’, "Sat", "Sun")

              because  Thursday,  16  August 2007 is the 11th working day (not
              counting Saturday and Sunday) after Wednesday, 1 August 2007.

              nonomitted has various uses.  For example, many schools run on a
              six-day cycle and the day number is not incremented on holidays.
              Suppose the school year starts with Day 1 on 4  September  2007.
              The following reminder will label day numbers in a calendar:

                 IF today() >= ’2007-09-04’
                     set daynum nonomitted(’2007-09-04’, today(), "Sat", "Sun")
                     REM OMIT SAT SUN SKIP CAL Day [(daynum % 6) + 1]
                 ENDIF

              Here’s  a  more  complex  example:  Suppose your normal garbage-
              collection day  is  Thursday,  but  if  any  of  Monday  through
              Thursday  of  a  week  is a holiday, the collection day moves to
              Friday.  Here’s one way to solve it:

                 FSET prev_monday(x) x - wkdaynum(x-1)

                 REM Thu Fri SATISFY [wkdaynum(trigdate()) == 4 && \
                          nonomitted(prev_monday(today()), today()+1) == 4 || \
                          wkdaynum(trigdate()) == 5 && \
                          nonomitted(prev_monday(today()), today()+1) <= 4] \
                          MSG Garbage Day

              Whew!  (You’ll need to see "THE SATISFY CLAUSE" later on.)  We’d
              better explain that one: The prev_monday helper function takes a
              date and returns the date  of  the  previous  Monday.   The  REM
              command  will  trigger  on  the  first  Thursday  or Friday that
              satisfies one of the following conditions:

              1) Either it’s a Thursday and there are exactly four non-omitted
              days between the previous Monday and tomorrow, or

              2)  It’s  a  Friday and there are four or fewer non-omitted days
              between the previous Monday  and  tomorrow.   We  need  the  "or
              fewer"  condition to handle the case of more than one holiday in
              a given week.  If that happens, garbage day still only moves  by
              one day.

              Obviously,  the  answer  you  get from nonomitted depends on the
              global OMIT context.  If you use moveable  OMITs,  you  may  get
              inconsistent results.

       now()  Returns  the  current  system time, as a TIME type.  This may be
              the actual time, or a time supplied on the command line.

       ord(i_num)
              Returns a string that is the ordinal number num.   For  example,
              ord(2) returns "2nd", and ord(213) returns "213th".

       ostype()
              Returns "UNIX".  Remind used to run on OS/2 and MS-DOS, but does
              not any longer.

       plural(i_num [,s_str1 [,s_str2]])
              Can take from one  to  three  arguments.   If  one  argument  is
              supplied, returns "s" if num is not 1, and "" if num is 1.

              If  two arguments are supplied, returns str1 + "s" if num is not
              1.  Otherwise, returns str1.

              If three arguments are supplied, returns str1 if num is  1,  and
              str2 otherwise.

       psmoon(i_phase [,i_size [,s_note [,i_notesize]]])
              [DEPRECATED]  Returns  a STRING consisting of PostScript code to
              draw a moon in the upper-left hand corner of the  calendar  box.
              Phase  specifies  the  phase of the moon, and is 0 (new moon), 1
              (first quarter), 2 (full moon) or 3 (third quarter).  If size is
              specified,  it  controls  the  radius  of the moon in PostScript
              units (1/72 inch.)  If it is not specified or is  negative,  the
              size of the day-number font is used.

              For  example, the following four lines place moon symbols on the
              PostScript calendar:

                        REM [trigger(moondate(0))] PS [psmoon(0)]
                        REM [trigger(moondate(1))] PS [psmoon(1)]
                        REM [trigger(moondate(2))] PS [psmoon(2)]
                        REM [trigger(moondate(3))] PS [psmoon(3)]

              If note is specified, the text is  used  to  annotate  the  moon
              display.   The  font is the same font used for calendar entries.
              If notesize is given, it specifies the font size to use for  the
              annotation, in PostScript units (1/72 inch.)  If notesize is not
              given, it defaults to the size used for calendar  entries.   (If
              you  annotate  the  display, be careful not to overwrite the day
              number -- Remind does not check for this.)  For example, if  you
              want  the time of each new moon displayed, you could use this in
              your reminder script:

                   REM [trigger(moondate(0))] PS [psmoon(0, -1, moontime(0)+"")]

              Note how the time is coerced to a string  by  concatenating  the
              null string.

       psshade(i_gray) or psshade(i_red, i_green, i_blue)
              [DEPRECATED]  Returns  a  STRING  that  consists  of  PostScript
              commands to  shade  a  calendar  box.   Num  can  range  from  0
              (completely   black)   to  100  (completely  white.)   If  three
              arguments are given, they specify red, green and blue  intensity
              from 0 to 100.  Here’s an example of how to use this:

                        REM Sat Sun PS [psshade(95)]

              The  above  command  emits  PostScript code to lightly shade the
              boxes for Saturday and Sunday in a PostScript calendar.

              Note that psmoon and psshade are deprecated; instead you  should
              use the SPECIAL SHADE and SPECIAL MOON reminders as described in
              "Out-of-Band Reminders."

       realcurrent()
              Returns (as a DATETIME)  the  true  date  and  time  of  day  as
              provided  by  the  operating  system.   This  is  in contrast to
              current(), which may return a time supplied on the command line.

       realnow()
              Returns  the  true  time  of  day  as  provided by the operating
              system.  This is in contrast to now(), which may return  a  time
              supplied on the command line.

       realtoday()
              Returns  the  date as provided by the operating system.  This is
              in contrast to Remind’s concept of "today", which may be changed
              if  it  is  running  in  calendar  mode,  or  if a date has been
              supplied on the command line.

       sgn(i_num)
              Returns -1 if num is negative, 1 if num is positive,  and  0  if
              num is zero.

       shell(s_cmd [,i_maxlen])
              Executes  cmd  as  a  system  command, and returns the first 511
              characters  of  output  resulting  from  cmd.   Any   whitespace
              character  in  the output is converted to a space.  Note that if
              RUN OFF has been executed, or the  -r  command-line  option  has
              been  used, shell() will result in an error, and cmd will not be
              executed.

       If  maxlen  is  specified,  then  shell()  returns  the  first   maxlen
       characters  of  output  (rather  than  the  first  511).   If maxlen is
       specified as a negative  number,  then  all  the  output  from  cmd  is
       returned.

       strlen(s_str)
              Returns the length of str.

       substr(s_str, i_start [,i_end])
              Returns  a STRING consisting of all characters in str from start
              up to and including end.  Characters are numbered  from  1.   If
              end is not supplied, then it defaults to the length of str.

       sunrise([dq_date])
              Returns  a  TIME indicating the time of sunrise on the specified
              date (default today().)  In high  latitudes,  there  may  be  no
              sunrise on a particular day, in which case sunrise() returns the
              INT 0 if the sun never sets, or 1440 if it never rises.

       sunset([dq_date])
              Returns a TIME indicating the time of sunset  on  the  specified
              date  (default  today().)   In  high  latitudes, there may be no
              sunset on a particular day, in which case sunset()  returns  the
              INT 0 if the sun never rises, or 1440 if it never sets.

              The  functions  sunrise() and sunset() are based on an algorithm
              in "Almanac for Computers for the year 1978" by L.  E.  Doggett,
              Nautical  Almanac  Office,  USNO.  They require the latitude and
              longitude to be specified  by  setting  the  appropriate  system
              variables.   (See "System Variables".)  The sun functions should
              be accurate to within about 2 minutes for latitudes  lower  than
              60  degrees.   The functions are available starting from version
              03.00.07 of Remind.

       time(i_hr, i_min)
              Creates a TIME with the hour and minute components specified  by
              hr and min.

       today()
              Returns  Remind’s  notion  of  "today."   This may be the actual
              system date, or a date supplied on the command line, or the date
              of the calendar entry currently being computed.

       trigdate()
              Returns  the  calculated  trigger date of the last REM or IFTRIG
              command.  If used in the body of a  REM  command,  returns  that
              command’s  trigger date.  If the most recent REM command did not
              yield a computable trigger date, returns the integer 0.

       trigdatetime()
              Similar to trigdate(), but returns a DATETIME if the most recent
              triggerable  REM  command  had an AT clause.  If there was no AT
              clause, returns a  DATE.   If  no  trigger  could  be  computed,
              returns the integer 0.

       trigger(d_date    [,t_time    [,i_utcflag]])    or   trigger(q_datetime
       [,i_utcflag])
              Returns a string suitable for use in a REM command, allowing you
              to  calculate  trigger  dates  in  advance.   (See  the  section
              "Expression pasting" for more information.)  Note that trigger()
              always returns its result in English, even for  foreign-language
              versions  of  Remind.   This is to avoid problems with certain C
              libraries that  do  not  handle  accented  characters  properly.
              Normally,  the  date  and  time  are  the  local  date and time;
              however,  if  utcflag  is  non-zero,  the  date  and  time   are
              interpreted  as  UTC  times,  and  are  converted to local time.
              Examples:

                   trigger(’1993/04/01’)

              returns "1 April 1993",

                   trigger(’1994/08/09’, 12:33)

              returns "9 August 1994 AT 12:33", as does:

                   trigger(’1994/08/09@12:33’).

              Finally:

                   trigger(’1994/12/01’, 03:00, 1)

              returns "30 November 1994 AT 22:00" for EST, which  is  5  hours
              behind UTC.  The value for your time zone may differ.

       trigtime()
              Returns  the time of the last REM command with an AT clause.  If
              the last REM did not have an AT clause, returns the integer 0.

       trigvalid()
              Returns 1 if the value returned by trigdate() is valid  for  the
              most recent REM command, or 0 otherwise.  Sometimes REM commands
              cannot calculate a trigger date.  For example, the following REM
              command can never be triggered:

                 REM Mon OMIT Mon SKIP MSG Impossible!

       typeof(x_arg)
              Returns "STRING", "INT", "DATE", "TIME" or "DATETIME", depending
              on the type of arg.

       tzconvert(q_datetime, s_srczone [,s_dstzone])
              Converts datetime from the time zone named  by  srczone  to  the
              time  zone named by dstzone.  If dstzone is omitted, the default
              system time zone is used.  The return value is a DATETIME.  Time
              zone  names  are system-dependent; consult your operating system
              for legal values.  Here is an example:

           tzconvert(’2007-07-08@01:14’, "Canada/Eastern", "Canada/Pacific")

                 returns

           2007-07-07@22:14

       upper(s_string)
              Returns a  STRING  with  all  lower-case  characters  in  string
              converted to upper-case.

       value(s_varname [,x_default])
              Returns  the  value  of  the  specified  variable.  For example,
              value("X"+"Y") returns the  value  of  variable  XY,  if  it  is
              defined.  If XY is not defined, an error results.

              However,  if you supply a second argument, it is returned if the
              varname is not defined.   The  expression  value("XY",  0)  will
              return  0  if  XY  is  not defined, and the value of XY if it is
              defined.

       version()
              Returns a string specifying the version of Remind.  For  version
              03.00.04,  returns  "03.00.04".   It  is  guaranteed that as new
              versions of Remind are released, the value returned by version()
              will  strictly  increase,  according  to  the  rules  for string
              ordering.

       wkday(dqi_arg)
              If arg is a DATE or DATETIME, returns a string representing  the
              day  of  the  week  of  the date.  If arg is an INT from 0 to 6,
              returns the corresponding weekday ("Sunday" to "Saturday").

       wkdaynum(dq_date)
              Returns a number from 0 to 6 representing the day-of-week of the
              specified   date.    (0  represents  Sunday,  and  6  represents
              Saturday.)

       year(dq_date)
              Returns a INT that is the year component of date.

EXPRESSION PASTING

       An extremely powerful feature of Remind is  its  macro  capability,  or
       "expression pasting."

       In  almost  any  situation where Remind is not expecting an expression,
       you can "paste" an expression in.  To do this, surround the  expression
       with square brackets.  For example:

            REM [trigger(mydate)] MSG foo

       This  evaluates  the  expression  "trigger(mydate)",  where "mydate" is
       presumably some pre-computed variable, and  then  "pastes"  the  result
       into the command-line for the parser to process.

       A  formal description of this is:  When Remind encounters a "pasted-in"
       expression, it evaluates the expression, and coerces the  result  to  a
       STRING.   It  then substitutes the string for the pasted-in expression,
       and continues parsing.  Note, however, that expressions  are  evaluated
       only once, not recursively.  Thus, writing:

            ["[a+b]"]

       causes Remind to read the token "[a+b]".  It does not interpret this as
       a pasted-in expression.  In fact, the only way to get a  literal  left-
       bracket into a reminder is to use ["["].

       You  can  use expression pasting almost anywhere.  However, there are a
       few exceptions:

       o      If Remind is expecting an expression, as in the SET command,  or
              the  IF  command,  then  no expression pasting takes place.  The
              expression is simply evaluated as if the  square  brackets  were
              not there.

       o      You cannot use expression pasting for the first token on a line.
              For example, the following will not work:

                 ["SET"] a 1

              This restriction is because Remind must be able to unambiguously
              determine  the  first  token  of  a  line  for  the flow-control
              commands (to be discussed later.)

              In fact, if Remind cannot determine the first token on  a  line,
              it  assumes  that it is a REM command.  If expression-pasting is
              used, Remind assumes it is a REM command.  Thus,  the  following
              three commands are equivalent:

                        REM 12 Nov 1993 AT 13:05 MSG BOO!
                        12 Nov 1993 AT 13:05 MSG BOO!
                        [12] ["Nov " + 1993] AT [12:05+60] MSG BOO!

       o      You  cannot  use  expression-pasting to determine the type (MSG,
              CAL, etc.) of a REM command.  You can paste  expressions  before
              and  after  the  MSG, etc keywords, but cannot do something like
              this:

                 REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]

       COMMON PITFALLS IN EXPRESSION PASTING

       Remember, when pasting  in  expressions,  that  extra  spaces  are  not
       inserted.  Thus, something like:

            REM[expr]MSG[expr]

       will probably fail.

       If  you use an expression to calculate a delta or back, ensure that the
       result is a positive number.  Something like:

            REM +[mydelta] Nov 12 1993 MSG foo

       will fail if mydelta happens to be negative.

FLOW CONTROL COMMANDS

       Remind has commands  that  control  the  flow  of  a  reminder  script.
       Normally, reminder scripts are processed sequentially.  However, IF and
       related commands allow you to process  files  conditionally,  and  skip
       sections that you don’t want interpreted.

       THE IF COMMAND

       The IF command has the following form:

            IF expr
                 t-command
                 t-command...
            ELSE
                 f-command
                 f-command...
            ENDIF

       Note  that the commands are shown indented for clarity.  Also, the ELSE
       portion can be omitted.  IF commands can be nested up to a small limit,
       probably around 8 or 16 levels of nesting, depending on your system.

       If the expr evaluates to a non-zero INT, or a non-null STRING, then the
       IF portion is considered true, and the  t-commands  are  executed.   If
       expr  evaluates  to  zero  or  null,  then  the f-commands (if the ELSE
       portion is present) are executed.  If  expr  is  not  of  type  INT  or
       STRING, then it is an error.

       Examples:

            IF defined("want_hols")
                 INCLUDE /usr/share/remind/holidays
            ENDIF

            IF today() > ’1992/2/10’
                 set missed_ap "You missed it!"
            ELSE
                 set missed_ap "Still have time..."
            ENDIF

       THE IFTRIG COMMAND

       The IFTRIG command is similar to an IF command, except that it computes
       a trigger (as  in  the  REM  command),  and  evaluates  to  true  if  a
       corresponding REM command would trigger.  Examples:

            IFTRIG 1 Nov
                 ; Executed on 1 Nov
            ELSE
                 ; Executed except on 1 Nov
            ENDIF

            IFTRIG 1 -1 OMIT Sat Sun +4
                 ; Executed on last working day of month,
                 ; and the 4 working days preceding it
            ELSE
                 ; Executed except on above days
            ENDIF

       Note  that  the  IFTRIG  command  computes a trigger date, which can be
       retrieved with the trigdate() function.  You can use all of the  normal
       trigger components, such as UNTIL, delta, etc in the IFTRIG command.

USER-DEFINED FUNCTIONS

       In addition to the built-in functions, Remind allows you to define your
       own functions.  The FSET command does this for you:

       FSET fname(args) expr

       Fname is the name of the  function,  and  follows  the  convention  for
       naming  variables.   Args  is  a comma-separated list of arguments, and
       expr is an expression.  Args can be empty, in which case you  define  a
       function taking no parameters.  Here are some examples:

            FSET double(x) 2*x
            FSET yeardiff(date1, date2) year(date1) - year(date2)
            FSET since(x) ord(year(trigdate())-x)

       The last function is useful in birthday reminders.  For example:

            REM 1 Nov +12 MSG Dean’s [since(1984)] birthday is %b.

       Dean  was  born  in 1984.  The above example, on 1 November 1992, would
       print:

            Dean’s 8th birthday is today.

       Notes:

       o      If you access a variable in expr that is  not  in  the  list  of
              arguments, the "global" value (if any) is used.

       o      Function   and  parameter  names  are  significant  only  to  12
              characters.

       o      The value() function always accesses the  "global"  value  of  a
              variable,  even  if  it  has  the same name as an argument.  For
              example:

                        fset func(x) value("x")
                        set x 1
                        set y func(5)

              The above sequence sets y to 1, which is the global value of  x.

       o      User-defined functions may call other functions, including other
              user-defined  functions.   However,  recursive  calls  are   not
              allowed.

       o      User-defined  functions  are  not  syntax-checked  when they are
              defined; parsing occurs only when they are called.

       o      If a user-defined function has  the  same  name  as  a  built-in
              function,  it  is ignored and the built-in function is used.  To
              prevent conflicts with future  versions  of  Remind  (which  may
              define  more built-in functions), you may wish to name all user-
              defined functions beginning with an underscore.

PRECISE SCHEDULING

       The WARN keyword allows precise control over advance warning in a  more
       flexible manner than the delta mechanism.  It should be followed by the
       name of a user-defined function, warn_function.

       If a warn_function is supplied, then it must take one argument of  type
       INT.   Remind  ignores  any  delta,  and  instead  calls  warn_function
       successively with the arguments 1, 2, 3, ...

       Warn_function’s return value n is interpreted as follows:

       o      If n is positive, then the reminder is triggered exactly n  days
              before its trigger date.

       o      If n is negative, then it is triggered n days before its trigger
              date, not counting OMITted days.

       As an example, suppose you wish to be warned of  American  Independence
       Day 5, 3, and 1 days in advance.  You could use this:

            FSET _wfun(x) choose(x, 5, 3, 1, 0)
            REM 4 July WARN _wfun MSG American Independence Day is %b.

       NOTES

       1      If  an error occurs during the evaluation of warn_function, then
              Remind stops calling it and simply issues the  reminder  on  its
              trigger date.

       2      If the absolute-values of the return values of warn_function are
              not monotonically decreasing, Remind stops calling it and issues
              the reminder on its trigger date.

       3      Warn_function should (as a matter of good style) return 0 as the
              final value in  its  sequence  of  return  values.   However,  a
              reminder   will   always  be  triggered  on  its  trigger  date,
              regardless of what warn_function does.

       Similarly to WARN, the SCHED keyword allows precise  control  over  the
       scheduling  of timed reminders.  It should be followed by the name of a
       user-defined function, sched_function.

       If a scheduling function is supplied, then it must take one argument of
       type  INT.  Rather than using the AT time, time delta, and time repeat,
       Remind calls the scheduling function to determine when to  trigger  the
       reminder.   The  first  time  the  reminder  is  queued, the scheduling
       function is called with an argument of 1.  Each time  the  reminder  is
       triggered, it is re-scheduled by calling the scheduling function again.
       On each call, the argument is incremented by one.

       The return value of the scheduling function must be an INT or  a  TIME.
       If  the  return  value  is  a  TIME,  then the reminder is re-queued to
       trigger at that time.  If it is a positive integer n, then the reminder
       is  re-queued  to  trigger at the previous trigger time plus n minutes.
       Finally, if it is a negative integer or zero, then the reminder is  re-
       queued  to  trigger n minutes before the AT time.  Note that there must
       be an AT clause for the SCHED clause to do anything.

       Here’s an example:

            FSET _sfun(x) choose(x, -60, 30, 15, 10, 3, 1, 1, 1, 1, 0)
            REM AT 13:00 SCHED _sfun MSG foo

       The reminder would first be triggered at 13:00-60 minutes, or at 12:00.
       It  would next be triggered 30 minutes later, at 12:30.  Then, it would
       be triggered at 12:45, 12:55, 12:58, 12:59, 13:00, 13:01 and 13:02.

       NOTES

       1      If an error occurs during the  evaluation  of  sched_func,  then
              Remind  reverts  to  using  the AT time and the delta and repeat
              values, and never calls sched_func again.

       2      If processing sched_func yields a time earlier than the  current
              system  time,  it  is repeatedly called with increasing argument
              until it yields a value greater than or  equal  to  the  current
              time.   However, if the sequence of values calculated during the
              repetition is not strictly increasing, then  Remind  reverts  to
              the default behaviour and never calls sched_func again.

       3      It  is  quite  possible  using  sched_func  to keep triggering a
              reminder even after the AT-time.  However, it is not possible to
              reschedule  a  reminder  past  midnight  -  no  crossing of date
              boundaries is allowed.   Also,  it  is  quite  possible  to  not
              trigger  a  reminder  on  the  AT time when you use a scheduling
              function.  However, if your scheduling  function  is  terminated
              (for  reasons  1  and  2) before the AT time of the reminder, it
              will be triggered at the  AT  time,  because  normal  processing
              takes over.

       4      Your  scheduling  functions  should  (as a matter of good style)
              return 0 when no more scheduling is required.  See the  example.

       5      All  scheduling  functions are evaluated after the entire Remind
              script has been read in.  So whatever function  definitions  are
              in effect at the end of the script are used.

THE SATISFY CLAUSE

       The form of REM that uses SATISFY is as follows:

       REM trigger SATISFY expr

       The  way  this  works is as follows:  Remind first calculates a trigger
       date,  in  the  normal  fashion.   Next,  it  sets  trigdate()  to  the
       calculated trigger date.  It then evaluates expr.  If the result is not
       the null string or zero, processing ends.  Otherwise,  Remind  computes
       the  next  trigger  date,  and re-tests expr.  This iteration continues
       until expr evaluates to non-zero or non-null, or  until  the  iteration
       limit specified with the -x command-line option is reached.

       If  expr  is  not  satisfied, then trigvalid() is set to 0.  Otherwise,
       trigvalid() is set to 1.  In any event, no error message is issued.

       This is really useful only if expr involves a call  to  the  trigdate()
       function; otherwise, expr will not change as Remind iterates.

       An example of the usefulness of SATISFY:  Suppose you wish to be warned
       of every Friday the 13th.  Your first attempt may be:

            # WRONG!
            REM Fri 13 +2 MSG Friday the 13th is %b.

       But this won’t work.  This reminder triggers on the first Friday on  or
       after  the  13th  of  each  month.   The  way  to  do it is with a more
       complicated sequence:

            REM 13 SATISFY wkdaynum(trigdate()) == 5
            IF trigvalid()
                 REM [trigger(trigdate())] +2 MSG \
                 Friday the 13th is %b.
            ENDIF

       Let’s see how this works.  The SATISFY clause iterates through all  the
       13ths of successive months, until a trigger date is found whose day-of-
       week is Friday (==  5).   If  a  valid  date  was  found,  we  use  the
       calculated  trigger  date  (converted  into  a  trigger format with the
       trigger() function) to set up the next reminder.

       We could also have written:

            REM Fri SATISFY day(trigdate()) == 13

       but this would result in more iterations, since  "Fridays"  occur  more
       often than "13ths of the month."

       This  technique of using one REM command to calculate a trigger date to
       be used by another command is quite powerful.  For example, suppose you
       wanted to OMIT Labour day, which is the first Monday in September.  You
       could use:

            # Note: SATISFY 1 is an idiom for "do nothing"
            REM Mon 1 Sept SATISFY 1
            OMIT [trigger(trigdate())]

       CAVEAT: This only omits the next Labour Day, not all Labour Days in the
       future.   This  could  cause  strange  results, as the OMIT context can
       change depending on the current date.  For  example,  if  you  use  the
       following command after the above commands:

            REM Mon AFTER msg hello

       the  result  will  not be as you expect.  Consider producing a calendar
       for September, 1992.  Labour Day was  on  Monday,  7  September,  1992.
       However,  when  Remind  gets  around  to  calculating  the  trigger for
       Tuesday, 8 September, 1992, the  OMIT  command  will  now  be  omitting
       Labour Day for 1993, and the "Mon AFTER" command will not be triggered.
       (But see the description of SCANFROM  in  the  section  "Details  about
       Trigger Computation.")

       It  is  probably  best  to  stay away from computing OMIT trigger dates
       unless you keep these pitfalls in mind.

       For versions of Remind starting from 03.00.07, you can include  a  MSG,
       RUN, etc. clause in a SATISFY clause as follows:

            REM trigger_stuff SATISFY [expr] MSG body

       Note  that  for this case only, the expr after SATISFY must be enclosed
       in braces.  It must come after all the other components of the trigger,
       and  immediately  before the MSG, RUN, etc. keyword.  If expr cannot be
       satisfied, then the reminder is not triggered.

       Thus, the "Friday the 13th" example can be expressed more compactly as:

            REM 13 +2 SATISFY [wkdaynum(trigdate()) == 5] \
                 MSG Friday the 13th is %b.

       And  you  can  trigger  a reminder on Mondays, Wednesdays and Thursdays
       occurring on odd-numbered days of the month with the following:

            REM Mon Wed Thu SATISFY [day(trigdate())%2] \
                 MSG Here it is!!!

DEBUGGING REMINDER SCRIPTS

       Although the command-line -d option is  useful  for  debugging,  it  is
       often  overkill.   For  example,  if  you  turn on the -dx option for a
       reminder file with many complex expressions, you’ll get a  huge  amount
       of output.  The DEBUG command allows you to control the debugging flags
       under program control.  The format is:

       DEBUG [+flagson] [-flagsoff]

       Flagson and flagsoff consist of strings of the characters "extvlf" that
       correspond  to  the  debugging  options  discussed  in the command-line
       options section.  If preceded with a "+", the  corresponding  group  of
       debugging  options  is  switched on.  Otherwise, they are switched off.
       For example, you  could  use  this  sequence  to  debug  a  complicated
       expression:

            DEBUG +x
            set a very_complex_expression(many_args)
            DEBUG -x

       THE DUMPVARS COMMAND

       The  command  DUMPVARS displays the values of variables in memory.  Its
       format is:

       DUMPVARS [var...]

       If  you  supply  a  space-separated  list  of   variable   names,   the
       corresponding  variables are displayed.  If you do not supply a list of
       variables, then all variables in  memory  are  displayed.   To  dump  a
       system variable, put its name in the list of variables to dump.  If you
       put a lone dollar sign in the list  of  variables  to  dump,  then  all
       system variables will be dumped.

       THE ERRMSG COMMAND

       The ERRMSG command has the following format:

       ERRMSG body

       The  body  is  passed through the substitution filter (with an implicit
       trigger date of today())  and  printed  to  the  error  output  stream.
       Example:

            IF !defined("critical_var")
                 ERRMSG You must supply a value for "critical_var"
                 EXIT
            ENDIF

       THE EXIT COMMAND

       The  above example also shows the use of the EXIT command.  This causes
       an  unconditional  exit  from  script  processing.   Any  queued  timed
       reminders are discarded.  If you are in calendar mode (described next),
       then the calendar processing is aborted.

       If you supply an INT-type expression after  the  EXIT  command,  it  is
       returned to the calling program as the exit status.  Otherwise, an exit
       status of 99 is returned.

       THE FLUSH COMMAND

       This command simply consists of the word FLUSH on  a  line  by  itself.
       The command flushes the standard output and standard error streams used
       by Remind.  This is not terribly useful to  most  people,  but  may  be
       useful  if  you run Remind as a subprocess of another program, and want
       to use pipes for communication.

CALENDAR MODE

       If you supply the -c, -s or -p command-line option, then Remind runs in
       "calendar   mode."    In   this  mode,  Remind  interprets  the  script
       repeatedly, performing one iteration through the whole  file  for  each
       day  in  the  calendar.   Reminders  that trigger are saved in internal
       buffers, and then inserted into the calendar in the appropriate places.

       If  you  also  supply the -a option, then Remind will not include timed
       reminders in the calendar.

       The -p option is used in conjunction with the Rem2PS program to produce
       a  calendar  in  PostScript format.  For example, the following command
       will send PostScript code to standard output:

            remind -p .reminders | rem2ps

       You can print a PostScript calendar by piping this to the lpr  command.

       If you have a reminder script called ".reminders", and you execute this
       command:

            remind -c .reminders jan 1993

       then Remind executes the script 31 times, once for each day in January.
       Each  time  it executes the script, it increments the value of today().
       Any reminders whose trigger date matches today() are entered  into  the
       calendar.

       MSG and CAL-type reminders, by default, have their entire body inserted
       into the calendar.  RUN-type reminders are not normally  inserted  into
       the  calendar.   However,  if  you enclose a portion of the body in the
       %"...%" sequence, only that portion is inserted.  For example, consider
       the following:

            REM 6 Jan MSG %"David’s birthday%" is %b

       In the normal mode, Remind would print "David’s birthday is today" on 6
       January.  However,  in  the  calendar  mode,  only  the  text  "David’s
       birthday" is inserted into the box for 6 January.

       If you explicitly use the %"...%" sequence in a RUN-type reminder, then
       the text between the delimiters is inserted into the calendar.  If  you
       use  the  sequence %"%" in a MSG or CAL-type reminder, then no calendar
       entry is produced for that reminder.

       PRESERVING VARIABLES

       Because Remind  iterates  through  the  script  for  each  day  in  the
       calendar,  slow operations may severely reduce the speed of producing a
       calendar.

       For example, suppose you set  the  variables  "me"  and  "hostname"  as
       follows:

            SET me shell("whoami")
            SET hostname shell("hostname")

       Normally,  Remind  clears  all variables between iterations in calendar
       mode.  However, if certain variables are slow to compute, and will  not
       change  between  iterations,  you  can "preserve" their values with the
       PRESERVE command.   Also,  since  function  definitions  are  preserved
       between  calendar iterations, there is no need to redefine them on each
       iteration.  Thus, you could use the following sequence:

            IF ! defined("initialized")
                 set initialized 1
                 set me shell("whoami")
                 set hostname shell("hostname")
                 fset func(x) complex_expr
                 preserve initialized me hostname
            ENDIF

       The operation is as  follows:   On  the  first  iteration  through  the
       script,  "initialized"  is  not defined.  Thus, the commands between IF
       and ENDIF are executed.  The PRESERVE command ensures that  the  values
       of   initialized,   me   and  hostname  are  preserved  for  subsequent
       iterations.  On the next iteration, the  commands  are  skipped,  since
       initialized has remained defined.  Thus, time-consuming operations that
       do not depend on the value of today() are done only once.

       System variables (those whose names start with ’$’)  are  automatically
       preserved between calendar iterations.

       Note  that  for  efficiency, Remind caches the reminder script (and any
       INCLUDEd files) in memory when producing a calendar.

       Timed reminders are sorted and placed into the calendar in time  order.
       These are followed by non-timed reminders.  Remind automatically places
       the time of timed  reminders  in  the  calendar  according  to  the  -b
       command-line  option.   Reminders in calendar mode are sorted as if the
       -g option had been used; you can change the sort order in calendar mode
       by explicitly using the -g option to specify a different order from the
       default.

       REPEATED EXECUTION

       If you supply a repeat parameter on the command line, and  do  not  use
       the  -c,  -p,  or  -s  options,  Remind operates in a similar manner to
       calendar  mode.   It   repeatedly   executes   the   reminder   script,
       incrementing  today()  with  each  iteration.   The  same  rules  about
       preserving variables and function definitions apply.  Note  that  using
       repeat  on the command line also enables the -q option and disables any
       -z option.  As an example, if you want to see how  Remind  will  behave
       for the next week, you can type:

            remind .reminders ’*7’

       If you want to print the dates of the next 1000 days, use:

            (echo ’banner %’; echo ’msg [today()]%’) | remind - ’*1000’

INITIALIZING VARIABLES ON THE COMMAND LINE

       The  -i  option  is  used to initialize variables on the Remind command
       line.  The format is -ivar=expr, where expr is  any  valid  expression.
       Note  that  you  may have to use quotes or escapes to prevent the shell
       from interpreting special characters in expr.  You can have as many  -i
       options  as  you  want  on  the command line, and they are processed in
       order.  Thus, if a variable is defined in one  -i  option,  it  can  be
       referred to by subsequent -i options.

       Note  that  if  you supply a date on the command line, it is not parsed
       until all options have been processed.  Thus, if you use today() in any
       of the -i expressions, it will return the same value as realtoday() and
       not the date supplied on the command line.

       Any variables defined on the command line are  preserved  as  with  the
       PRESERVE command.

       You  should  not  have  any  spaces between the -i option and the equal
       sign; otherwise, strange variable names are created that  can  only  be
       accessed with the value() or defined() functions.

       You can also define a function on the command line by using:

       -ifunc(args)=definition

       Be sure to protect special characters from shell interpretation.

MORE ABOUT POSTSCRIPT

       The  PS  and  PSFILE  reminders  pass  PostScript  code directly to the
       printer.  They differ in that the  PS-type  reminder  passes  its  body
       directly to the PostScript output (after processing by the substitution
       filter) while  the  PSFILE-type’s  body  should  simply  consist  of  a
       filename.   The  Rem2PS program will open the file named in the PSFILE-
       type reminder, and include its contents in the PostScript output.

       The PostScript-type reminders for a particular day are included in  the
       PostScript  output in sorted order of priority.  Note that the order of
       PostScript commands has  a  major  impact  on  the  appearance  of  the
       calendars.   For  example, PostScript code to shade a calendar box will
       obliterate code to draw a moon symbol if the moon symbol code is placed
       in  the  calendar first.  For this reason, you should not provide PS or
       PSFILE-type reminders with priorities; instead, you should ensure  that
       they  appear  in  the reminder script in the correct order.  PostScript
       code should draw objects working from the background to the foreground,
       so  that  foreground  objects properly overlay background ones.  If you
       prioritize these reminders and run the  script  using  descending  sort
       order for priorities, the PostScript output will not work.

       All of the PostScript code for a particular date is enclosed in a save-
       restore  pair.   However,  if  several  PostScript-type  reminders  are
       triggered  for a single day, each section of PostScript is not enclosed
       in  a  save-restore  pair  -  instead,  the  entire  body  of  included
       PostScript is enclosed.

       PostScript-type reminders are executed by the PostScript printer before
       any regular calendar entries.   Thus,  regular  calendar  entries  will
       overlay the PostScript-type reminders, allowing you to create shaded or
       graphical backgrounds for particular days.

       Before executing your PostScript code, the  origin  of  the  PostScript
       coordinate  system  is positioned to the bottom left-hand corner of the
       "box" in the calendar representing today().  This location  is  exactly
       in  the  middle  of the intersection of the bottom and left black lines
       delineating the box - you may have to  account  for  the  thickness  of
       these lines when calculating positions.

       Several  PostScript  variables are available to the PostScript code you
       supply.  All distance and size variables are in PostScript units  (1/72
       inch.)  The variables are:

       LineWidth
              The width of the black grid lines making up the calendar.

       Border The  border  between  the center of the grid lines and the space
              used to print calendar entries.  This border is  normally  blank
              space.

       BoxWidth and BoxHeight
              The  width and height of the calendar box, from center-to-center
              of the black gridlines.

       InBoxHeight
              The height from the center of the bottom black gridline  to  the
              top  of the regular calendar entry area.  The space from here to
              the top of the box is used only to draw the day number.

       /DayFont, /EntryFont, /SmallFont, /TitleFont and /HeadFont
              The fonts used to draw the day numbers,  the  calendar  entries,
              the  small  calendars,  the calendar title (month, year) and the
              day-of-the-week headings, respectively.

       DaySize, EntrySize, TitleSize and HeadSize
              The sizes of the above fonts.  (The size of the  small  calendar
              font  is not defined here.)  For example, if you wanted to print
              the Hebrew date next to the regular day number in the  calendar,
              use:

            REM PS Border BoxHeight Border sub DaySize sub moveto \
               /DayFont findfont DaySize scalefont setfont \
               ([hebday(today())] [hebmon(today())]) show

              Note how /DayFont and DaySize are used.

       Note  that  if  you  supply  PostScript code, it is possible to produce
       invalid PostScript files.  Always test your PostScript thoroughly  with
       a  PostScript  viewer before sending it to the printer.  You should not
       use any document structuring comments in your PostScript code.

DAEMON MODE

       If you use the -z command-line option,  Remind  runs  in  the  "daemon"
       mode.   In  this mode, no "normal" reminders are issued.  Instead, only
       timed reminders are collected and queued, and are then issued  whenever
       they reach their trigger time.

       In   addition,   Remind  wakes  up  every  few  minutes  to  check  the
       modification date on the reminder script (the filename supplied on  the
       command  line.)   If Remind detects that the script has changed, it re-
       executes itself in daemon mode, and interprets the changed script.

       In daemon mode, Remind also re-reads the remind script when it  detects
       that the system date has changed.

       In  daemon  mode,  Remind acts as if the -f option had been used, so to
       run in the daemon mode in the background, use:

            remind -z .reminders &

       If you use sh or bash, you may have  to  use  the  "nohup"  command  to
       ensure that the daemon is not killed when you log out.

SORTING REMINDERS

       The -g option causes Remind to sort reminders by trigger date, time and
       priority before issuing them.  Note that reminders are still calculated
       in  the  order  encountered  in the script.  However, rather than being
       issued immediately, they are saved in an internal buffer.  When  Remind
       has  finished  processing  the script, it issues the saved reminders in
       sorted order.  The -g option can be followed by up to three  characters
       that  must  all  be "a" or "d".  The first character specifies the sort
       order by trigger date (ascending or descending), the  second  specifies
       the  sort  order by trigger time and the third specifies the sort order
       by priority.  The default is to sort all fields in ascending order.

       In ascending order, reminders are issued with the most imminent  first.
       Descending  order  is  the  reverse.   Reminders  are  always sorted by
       trigger date, and reminders with the same trigger date are then  sorted
       by  trigger  time.   Non-timed  reminders are always issued after timed
       reminders in this mode.  If two reminders have the same date and  time,
       then the priority is used to break ties.  Reminders with the same date,
       time and priority are issued in the order they were encountered.

       You can define a user-defined function called SORTBANNER that takes one
       DATE-type argument.  In sort mode, the following sequence happens:

       If  Remind  notices  that  the  next  reminder to issue has a different
       trigger date from the previous one (or if it is the  first  one  to  be
       issued),  then  SORTBANNER  is  called  with  the  trigger  date as its
       argument.  The result is coerced to a string, and  passed  through  the
       substitution  filter  with the appropriate trigger date.  The result is
       then displayed.

       Here’s an example - consider the following fragment:

            # Switch off the normal banner
            BANNER %
            REM 11 March 1993 ++1 MSG Not so important
            REM 17 March 1993 ++7 MSG Way in the future
            REM 10 March 1993 MSG Important Reminder
            REM 11 March 1993 ++1 MSG Not so important - B
            FSET sortbanner(x) iif(x == today(), \
                 "***** THINGS TO DO TODAY *****", \
                 "----- Things to do %b -----")

       Running this with the  -gaa  option  on  10  March  1993  produces  the
       following output:

            ***** THINGS TO DO TODAY *****

            Important Reminder

            ----- Things to do tomorrow -----

            Not so important

            Not so important - B

            ----- Things to do in 7 days’ time -----

            Way in the future

       You  can  use  the args() built-in function to determine whether or not
       SORTBANNER has been defined.  (This could  be  used,  for  example,  to
       provide  a  default  definition  for  SORTBANNER  in a system-wide file
       included at the end of the user’s file.)  Here’s an example:

            # Create a default sortbanner function if it hasn’t already
            # been defined
            if args("sortbanner") != 1
                 fset sortbanner(x) "--- Things to do %b ---"
            endif

MSGPREFIX() AND MSGSUFFIX()

       You can define two functions in  your  script  called  msgprefix()  and
       msgsuffix().   They should each accept one argument, a number from 0 to
       9999.

       In normal mode, for MSG- and MSF-type reminders, the following sequence
       occurs when Remind triggers a reminder:

       o      If  msgprefix() is defined, it is evaluated with the priority of
              the reminder as its argument.  The result is printed.  It is not
              passed through the substitution filter.

       o      The body of the reminder is printed.

       o      If  msgsuffix() is defined, it is evaluated with the priority of
              the reminder as its argument.  The result is printed.  It is not
              passed through the substitution filter.

       Here’s   an   example:   The  following  definition  causes  priority-0
       reminders to be preceded by "URGENT", and priority-6000 reminders to be
       preceded by "(not important)".

            fset msgprefix(x) iif(x==0, "URGENT: ", \
                 x==6000, "(not important) ", "")

       In  Calendar Mode (with the -c, -s or -p options), an analogous pair of
       functions named calprefix() and calsuffix() can be defined.  They  work
       with  all  reminders  that produce an entry in the calendar (i.e., CAL-
       and possibly RUN-type reminders as well as MSG-type reminders.)

       NOTES

       Normally, the body of a reminder is  followed  by  a  carriage  return.
       Thus,  the results of msgsuffix() will appear on the next line.  If you
       don’t want this, end the body of the reminder with a  percentage  sign,
       "%".   If  you  want  a  space between your reminders, simply include a
       carriage return (char(13)) as part of the msgsuffix() return value.

       If  Remind  has  problems  evaluating   msgprefix(),   msgsuffix()   or
       sortbanner(),  you will see a lot of error messages.  For an example of
       this, define the following:

            fset msgprefix(x) x/0

FOREIGN LANGUAGE SUPPORT

       Your version of Remind may have been compiled  to  support  a  language
       other  than  English.   This  support  may or may not be complete - for
       example, all  error  and  usage  messages  may  still  be  in  English.
       However,  at a minimum, foreign-language versions of Remind will output
       names of months and  weekdays  in  the  foreign  language.   Also,  the
       substitution  mechanism  will  substitute  constructs  suitable for the
       foreign language rather than for English.

       A foreign-language version of Remind will accept either the English  or
       foreign-language  names  of  weekdays  and months in a reminder script.
       However, for compatibility between versions of Remind, you  should  use
       only  the  English  names in your scripts.  Also, if your C compiler or
       run-time libraries are not "8-bit clean" or don’t understand  the  ISO-
       Latin  character  set, month or day names with accented letters may not
       be recognized.

THE HEBREW CALENDAR

       Remind has support for the  Hebrew  calendar,  which  is  a  luni-solar
       calendar.   This  allows  you  to create reminders for Jewish holidays,
       jahrzeits (anniversaries of deaths) and smachot (joyous occasions.)

       THE HEBREW YEAR

       The Hebrew year has 12 months, alternately 30 and 29  days  long.   The
       months  are: Tishrey, Heshvan, Kislev, Tevet, Shvat, Adar, Nisan, Iyar,
       Sivan, Tamuz, Av and Elul.  In Biblical  times,  the  year  started  in
       Nisan,  but Rosh Hashana (Jewish New Year) is now celebrated on the 1st
       and 2nd of Tishrey.

       In a cycle of 19 years, there are 7 leap years, being years  3,  6,  8,
       11,  14,  17 and 19 of the cycle.  In a leap year, an extra month of 30
       days is added before Adar.  The two Adars are called Adar A and Adar B.

       For  certain  religious  reasons,  the  year  cannot start on a Sunday,
       Wednesday or Friday.  To adjust for this, a day is taken off Kislev  or
       added  to Heshvan.  Thus, a regular year can have from 353 to 355 days,
       and a leap year from 383 to 385.

       When Kislev or Heshvan is short, it is called chaser, or lacking.  When
       it is long, it is called shalem, or full.

       The  Jewish  date  changes  at sunset.  However, Remind will change the
       date at midnight, not sunset.  So in  the  period  between  sunset  and
       midnight, Remind will be a day earlier than the true Jewish date.  This
       should not be much of a problem in practice.

       The computations for the Jewish calendar  were  based  on  the  program
       "hdate"  written  by Amos Shapir of the Hebrew University of Jerusalem,
       Israel.  He also supplied the preceding explanation of the calendar.

       HEBREW DATE FUNCTIONS

       hebday(d_date)
              Returns the day of the Hebrew month corresponding  to  the  date
              parameter.   For  example, 12 April 1993 corresponds to 21 Nisan
              5753.  Thus, hebday(’1993/04/12’) returns 21.

       hebmon(d_date)
              Returns the name of the Hebrew month corresponding to date.  For
              example, hebmon(’1993/04/12’) returns "Nisan".

       hebyear(d_date)
              Returns  the  Hebrew  year  corresponding to date.  For example,
              hebyear(’1993/04/12’) returns 5753.

       hebdate(i_day, s_hebmon [,id_yrstart [,i_jahr [,i_aflag]]])
              The hebdate() function is the most complex of the Hebrew support
              functions.   It  can  take  from 2 to 5 arguments.  It returns a
              DATE corresponding to the Hebrew date.

              The day parameter can range from 1 to 30, and specifies the  day
              of the Hebrew month.  The hebmon parameter is a string that must
              name one of the Hebrew months specified above.   Note  that  the
              month  must  be  spelled  out  in  full,  and  use  the  English
              transliteration shown previously.  You can also specify "Adar A"
              and "Adar B."  Month names are not case-sensitive.

              The  yrstart parameter can either be a DATE or an INT.  If it is
              a DATE, then the hebdate() scans for the first Hebrew date on or
              after that date.  For example:

                        hebdate(15, "Nisan", ’1990/01/01’)

              returns  1990/03/30,  because that is the first occurrence of 15
              Nisan on or after 1 January 1990.

              If yrstart is an INT, it is interpreted as a Hebrew year.  Thus:

                        hebdate(22, "Kislev", 5756)

              returns  1995/12/15, because that date corresponds to 22 Kislev,
              5756.  Note that none of the Hebrew  date  functions  will  work
              with dates outside Reminds normal range for dates.

              If yrstart is not supplied, it defaults to today().

              The jahr modifies the behaviour of hebdate() as follows:

              If  jahr is 0 (the default), then hebdate() keeps scanning until
              it finds a date that exactly  satisfies  the  other  parameters.
              For example:

                        hebdate(30, "Adar A", 1993/01/01)

              returns  1995/03/02,  corresponding  to 30 Adar A, 5755, because
              that is the next occurrence of 30 Adar A after 1 January,  1993.
              This  behaviour  is  appropriate  for  Purim  Katan,  which only
              appears in leap years.

              If jahr is 1, then the date is modified as follows:

              o      30 Heshvan is converted to 1 Kislev in years when Heshvan
                     is chaser

              o      30 Kislev is converted to 1 Tevet in years when Kislev is
                     chaser

              o      30 Adar A is converted to 1 Nisan in non-leapyears

              o      Other dates in Adar A are moved to the corresponding  day
                     in Adar in non-leapyears

              This behaviour is appropriate for smachot (joyous occasions) and
              for some jahrzeits - see "JAHRZEITS."

              if jahr is 2, then the date is modified as follows:

              o      30 Kislev and 30 Heshvan are converted to 29  Kislev  and
                     29 Heshvan, respectively, if the month is chaser

              o      30 Adar A is converted to 30 Shvat in non-leapyears

              o      Other  dates in Adar A are moved to the corresponding day
                     in Adar in non-leapyears

              if jahr is not 0, 1, or 2, it is interpreted as a  Hebrew  year,
              and  the  behaviour  is  calculated  as  described  in  the next
              section, "JAHRZEITS."

              The aflag parameter modifies the behaviour of the  function  for
              dates  in  Adar  during  leap  years.  The aflag is only used if
              yrstart is a DATE type.

              The aflag only affects date calculations if hebmon is  specified
              as "Adar".  In leap years, the following algorithm is followed:

              o      If  aflag  is  0,  then  the date is triggered in Adar B.
                     This is the default.

              o      If aflag is 1, then the date  is  triggered  in  Adar  A.
                     This  may  be  appropriate for jahrzeits in the Ashkenazi
                     tradition; consult a rabbi.

              o      If aflag is 2, then the date is triggered in both Adar  A
                     and  Adar  B  of  a  leap  year.  Some Ashkenazim perform
                     jahrzeit in both Adar A and Adar B.

       JAHRZEITS

       A jahrzeit is a yearly commemoration of someone’s death.   It  normally
       takes  place  on  the  anniversary  of the death, but may be delayed if
       burial is delayed - consult a rabbi for more information.

       In addition, because some months change length, it is not obvious which
       day the anniversary of a death is.  The following rules are used:

       o      If  the  death  occurred  on 30 Heshvan, and Heshvan in the year
              after the death is chaser, then the jahrzeit is observed  on  29
              Heshvan  in  years  when  Heshvan  is  chaser.   Otherwise,  the
              yahrzeit is observed on 1 Kislev when Heshvan is chaser.

       o      If the death occurred on 30 Kislev, and Kislev in the year after
              the  death is chaser, then the jahrzeit is observed on 29 Kislev
              in years when Kislev is  chaser.   Otherwise,  the  yahrzeit  is
              observed on 1 Tevet when Kislev is chaser.

       o      If  the  death  occurred  on 1-29 Adar A, it is observed on 1-29
              Adar in non-leapyears.

       o      If the death occurred on 30 Adar A, it is observed on  30  Shvat
              in a non-leapyear.

       Specifying  a  Hebrew  year  for  the jahr parameter causes the correct
       behaviour to be selected for a death in that year.  You may  also  have
       to specify aflag, depending on your tradition.

       The  jahrzeit information was supplied by Frank Yellin, who quoted "The
       Comprehensive  Hebrew  Calendar"  by  Arthur  Spier,  and  "Calendrical
       Calculations" by E. M. Reingold and Nachum Dershowitz.

OUT-OF-BAND REMINDERS

       The  SPECIAL  keyword  is used to transmit "out-of-band" information to
       Remind backends, such as tkremind or Rem2PS.  They are used  only  when
       piping  data from a remind -p line.  (Note that the COLOR special is an
       exception; it downgrades to the equivalent of MSG  in  reminds  normal
       mode of operation.)

       The  various  SPECIALs  recognized  are  particular  for  each backend;
       however, there are three SPECIALs that all backends should  attempt  to
       support.    They  are  currently  supported  by  Rem2PS,  tkremind  and
       rem2html.

       The SHADE special replaces the psshade() function.  Use it like this:
            REM Sat Sun SPECIAL SHADE 128
            REM Mon SPECIAL SHADE 255 0 0
       The SHADE keyword is followed by either one or three numbers, from 0 to
       255.   If  one  number  is  supplied, it is interpreted as a grey-scale
       value from black (0) to white (255).  If three  numbers  are  supplied,
       they  are  interpreted  as  RGB  components from minimum (0) to maximum
       (255).  The example above shades weekends a fairly dark grey and  makes
       Mondays  a  fully-saturated  red.   (These shadings appear in calendars
       produced by Rem2PS, tkremind and rem2html.)

       The MOON special replaces the psmoon() function.  Use it like this:
            REM [trigger(moondate(0))] SPECIAL MOON 0
            REM [trigger(moondate(1))] SPECIAL MOON 1
            REM [trigger(moondate(2))] SPECIAL MOON 2
            REM [trigger(moondate(3))] SPECIAL MOON 3
       These draw little moons on the various calendars.  The complete  syntax
       of the MOON special is as follows:
            ... SPECIAL MOON phase moonsize fontsize msg

       Phase  is  a  number from 0 to 3, with 0 representing a new moon, 1 the
       first quarter, 2 a full moon and 3 the last quarter.

       moonsize is the diameter in PostScript units of the moon to  draw.   If
       omitted or supplied as -1, the backend chooses an appropriate size.

       fontsize is the font size in PostScript units of the msg

       Msg is additional text that is placed near the moon glyph.

       Note  that  only the Rem2PS backend supports moonsize and fontsize; the
       other backends use fixed sizes.

       The COLOR special lets you place colored  reminders  in  the  calendar.
       Use it like this:

            REM ... SPECIAL COLOR 255 0 0 This is a bright red reminder
            REM ... SPECIAL COLOR 0 128 0 This is a dark green reminder

       Immediately  following  COLOR  should  be three decimal numbers ranging
       from 0 to 255 specifying red, green and blue intensities, respectively.
       The rest of the line is the text to put in the calendar.

       The  COLOR special is "doubly special", because in its normal operating
       mode, remind treats a COLOR special  just  like  a  MSG-type  reminder.
       Also,  if  you  invoke Remind with -cc..., then it approximates SPECIAL
       COLOR reminders on your terminal.

MISCELLANEOUS

       COMMAND ABBREVIATIONS

       The following tokens can be abbreviated:

       o      REM can be omitted - it is implied if no other valid command  is
              present.

       o      CLEAR-OMIT-CONTEXT --> CLEAR

       o      PUSH-OMIT-CONTEXT --> PUSH

       o      POP-OMIT-CONTEXT --> POP

       o      DUMPVARS --> DUMP

       o      BANNER --> BAN

       o      INCLUDE --> INC

       o      SCANFROM --> SCAN

       NIFTY EXAMPLES

       This section is a sampling of what you can do with Remind.

            REM 5 Feb 1991 AT 14:00 +45 *30 \
            RUN mail -s "Meeting at %2" $LOGNAME </dev/null &

       On  5 February, 1991, this reminder will mail you reminders of a 2:00pm
       meeting at 1:15, 1:45 and 2:00.  The subject of the mail  message  will
       be "Meeting at 2:00pm" and the body of the message will be blank.

            REM AT 17:00 RUN echo "5:00pm - GO HOME!" | xless -g +0+0 &

       This  reminder  will  pop  up an xless window at 5:00pm every day.  The
       xless window will contain the line "5:00pm - GO HOME!"

            REM AT 23:59 RUN (sleep 120; remind -a [filename()]) &

       This reminder will run at one minute to midnight.  It will cause a  new
       Remind  process  to start at one minute past midnight.  This allows you
       to have a continuous reminder service so you can work through the night
       and still get timed reminders for early in the morning.  Note that this
       trick is no longer necessary, providing you run Remind in daemon  mode.

            remind -c12 /dev/null Jan 1993

       This  invocation  of Remind will cause it to print a calendar for 1993,
       with all entries left blank.

            REM CAL [trigdate()-date(year(trigdate()), 1, 1)+1]

       This example puts an entry in each box of a calendar showing the number
       (1-365 or 366) of the day of the year.

            REM Tue 2 Nov SATISFY (year(trigdate())%4) == 0
            IF trigvalid()
                 REM [trigger(trigdate())] ++5 MSG \
                 U.S. Presidential Election!!
            ENDIF

       This  example  warns  you  5  days  ahead of each American presidential
       election.  The first REM command calculates the first Tuesday after the
       first  Monday in November.  (This is equivalent to the first Tuesday on
       or after 2 November.)  The SATISFY clause ensures that the trigger date
       is issued only in election years, which are multiples of 4.  The second
       REM command actually issues the reminder.

       DETAILS ABOUT TRIGGER COMPUTATION

       Here is a conceptual description of how triggers are calculated.   Note
       that  Remind  actually  uses  a  much more efficient procedure, but the
       results are the same as if the conceptual procedure had been  followed.

       Remind starts from the current date (that is, the value of today()) and
       scans forward, examining each day one at a time until it finds  a  date
       that  satisfies  the  trigger,  or  can prove that no such dates (on or
       later than today()) exist.

       If Remind is  executing  a  SATISFY-type  reminder,  it  evaluates  the
       expression  with  trigdate()  set  to  the  date  found  above.  If the
       expression evaluates to zero or the null string, Remind  continues  the
       scanning  procedure  described  above,  starting with the day after the
       trigger found above.

       The SCANFROM clause (having a syntax similar to UNTIL) can  modify  the
       search  strategy  used.   In  this  case,  Remind  begins  the scanning
       procedure at scan_date, which is the date  specified  in  the  SCANFROM
       clause.  For example:

            REM Mon 1 SCANFROM 17 Jan 1992 MSG Foo

       The example above will always have a trigger date of Monday, 3 February
       1992.  That is because Remind starts scanning from 17 January 1992, and
       stops scanning as soon as it hits a date that satisfies "Mon 1."

       The  main  use of SCANFROM is in situations where you want to calculate
       the positions of floating holidays.  Consider the  Labour  Day  example
       shown  much  earlier.  Labour Day is the first Monday in September.  It
       can move over a range of 7 days.  Consider the following sequence:

            REM Mon 1 Sept SCANFROM [trigger(today()-7)] SATISFY 1
            OMIT [trigger(trigdate())]

            REM Mon AFTER MSG Hello

       The SCANFROM clause makes sure that Remind begins scanning from 7  days
       before  the current date.  This ensures that Labour Day for the current
       year will continue to be triggered until 7 days after it has  occurred.
       This allows you to safely use the AFTER keyword as shown.

       In  general,  use SCANFROM as shown for safe movable OMITs.  The amount
       you should scan back by (7 days in the example above)  depends  on  the
       number  of possible consecutive OMITted days that may occur, and on the
       range of the movable holiday.  Generally, a value of 7 is safe.

       The FROM clause operates almost like the  counterpoint  to  UNTIL.   It
       prevents  the  reminder  from  triggering  before  the  FROM date.  For
       example, the following reminder:

            REM Mon Thu FROM 23 Jul 2007 UNTIL 2 Aug 2007 MSG Test

       will trigger on Mondays and Thursdays between 23 July 2007 and 2 August
       2007 inclusive.

       FROM  is  really just syntactic sugar; you could implement the reminder
       above as follows:

            REM Mon Thu SCANFROM [trigger(max(today(), ’2007-07-23’))] \
                   UNTIL 2 Aug 2007 MSG Test

       but that’s a lot  harder  to  read.   Internally,  Remind  treats  FROM
       exactly as illustrated using SCANFROM.  For that reason, you cannot use
       both FROM and SCANFROM.

       Note that if you use one REM  command  to  calculate  a  trigger  date,
       perform  date  calculations  (addition or subtraction, for example) and
       then use the modified date in a subsequent REM command, the results may
       not  be  what  you intended.  This is because you have circumvented the
       normal scanning mechanism.  You should try to write REM  commands  that
       compute  trigger  dates  that  can be used unmodified in subsequent REM
       commands.  The file "defs.rem" that comes with the Remind  distribution
       contains examples.

       DETAILS ABOUT TRIGVALID()

       The  trigvalid() function returns 1 if Remind could find a trigger date
       for the previous REM or IFTRIG command.  More specifically, it  returns
       1  if  Remind finds a date not before the starting date of the scanning
       that satisfies the trigger.  In addition, there is one special case  in
       which trigvalid() returns 1 and trigdate() returns a meaningful result:

       If the REM or IFTRIG command did  not  contain  an  UNTIL  clause,  and
       contained  all  of the day, month and year components, then Remind will
       correctly compute a trigger date, even if it happens to be  before  the
       start  of  scanning.  Note that this behaviour is not true for versions
       of Remind prior to 03.00.01.

AUTHOR

       Remind  is   now   supported   by   Roaring   Penguin   Software   Inc.
       (http://www.roaringpenguin.com)

       David  F.  Skoll  <dfs@roaringpenguin.com> wrote Remind.  The moon code
       was copied largely unmodified from  "moontool"  by  John  Walker.   The
       sunrise  and  sunset  functions  use  ideas  from  programs  by Michael
       Schwartz and Marc T. Kaufman.  The Hebrew calendar  support  was  taken
       from  "hdate"  by  Amos  Shapir.   OS/2  support  was  done  by  Darrel
       Hankerson, Russ  Herman,  and  Norman  Walsh.   The  supported  foreign
       languages  and  their  translators  are listed below.  Languages marked
       "complete" support  error  messages  and  usage  instructions  in  that
       language; all others only support the substitution filter mechanism and
       month/day names.

       German -- Wolfgang Thronicke

       Dutch -- Willem Kasdorp and Erik-Jan Vens

       Finnish -- Mikko Silvonen (complete)

       French -- Laurent Duperval (complete)

       Norwegian -- Trygve Randen

       Danish -- Mogens Lynnerup

       Polish -- Jerzy Sobczyk (complete)

       Brazilian Portuguese -- Marco Paganini (complete)

       Italian -- Valerio Aimale

       Romanian -- Liviu Daia

       Spanish -- Rafa Couto

       Icelandic -- Björn Davíðsson

BUGS

       There’s  no  good  reason  why  read-only  system  variables  are   not
       implemented  as  functions,  or why functions like version(), etc.  are
       not implemented as read-only system variables.

       Hebrew dates in Remind change at midnight instead of sunset.

       Language should be selectable at  run-time,  not  compile-time.   Don’t
       expect  this  to  happen  soon!   Remind  has some built-in limits (for
       example, number of global OMITs.)

BIBLIOGRAPHY

       Nachum Dershowitz and Edward M. Reingold,  "Calendrical  Calculations",
       Software-Practice and Experience, Vol. 20(9), Sept. 1990, pp 899-928.

       L.  E.  Doggett,  Almanac  for  computers  for  the year 1978, Nautical
       Almanac Office, USNO.

       Richard Siegel and Michael and  Sharon  Strassfeld,  The  First  Jewish
       Catalog, Jewish Publication Society of America.

SEE ALSO

       rem, rem2ps, tkremind