1REMIND(1)                   General Commands Manual                  REMIND(1)
2
3
4

NAME

6       remind - a sophisticated reminder service
7

SYNOPSIS

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

DESCRIPTION

12       Remind  reads  the supplied filename and executes the commands found in
13       it.  The commands  are  used  to  issue  reminders  and  alarms.   Each
14       reminder  or alarm can consist of a message sent to standard output, or
15       a program to be executed.
16
17       If filename is specified as a single dash '-', then  Remind  takes  its
18       input from standard input.  This also implicitly enables the -o option,
19       described below.
20

OPTIONS

22       Remind has a slew of options.  If you're new  to  the  program,  ignore
23       them for now and skip to the section "Reminder Files".
24
25       -n     The -n option causes Remind to print the next occurrence of each
26              reminder in a simple calendar format.  You can sort this by date
27              by piping the output through sort(1).
28
29       -r     The  -r option disables RUN directives and the shell() function.
30              As of Remind 3.00.17, using -u implies -r.
31
32       -cn    The -c option causes Remind to produce a calendar that  is  sent
33              to  standard  output.  If you supply a number n, then a calendar
34              will be generated for n months, starting with the current month.
35              By  default,  a calendar for only the current month is produced.
36              If n starts with '+', then a calendar for n weeks is produced.
37
38       -wcol[,pad[,spc]]]
39              The -w option specifies the output width, padding and spacing of
40              the formatted calendar output.  Col specifies the number of col‐
41              umns in the output device, and defaults to  80.   Pad  specifies
42              how  many  lines  to  use  to  "pad" empty calendar boxes.  This
43              defaults to 5.  If you have many reminders on certain days  that
44              make  your  calendar  too  large  to  fit on a page, you can try
45              reducing pad to make the empty boxes smaller.  Spc specifies how
46              many  blank  lines to leave between the day number and the first
47              reminder entry.  It defaults to 1.
48
49              Any of col, pad or spc can be omitted, providing you provide the
50              correct number of commas.  Don't use any spaces in the option.
51
52       -s[a]n The  -s option is very similar to the -c option, except that the
53              output calendar is not formatted.  It is  listed  in  a  "simple
54              format"  that can be used as input for more sophisticated calen‐
55              dar-drawing programs.  If n starts with "+", then it  is  inter‐
56              preted as a number of weeks.
57
58              If  you  immediately follow the s with the letter a, then Remind
59              displays reminders on the calendar  on  the  day  they  actually
60              occur  as  well  as  on  any  preceding  days  specified  by the
61              reminder's delta.
62
63       -p[a]n The -p option is very similar to the -s option, except that  the
64              output  contains  additional  information  for use by the Rem2PS
65              program, which creates a PostScript calendar.  For this  option,
66              n  cannot  start  with  "+"; it must specify a number of months.
67              The format of the -p output is described in  the  rem2ps(1)  man
68              page.   If  you immediately follow the p with the letter a, then
69              Remind displays reminders on the calendar on the day they  actu‐
70              ally  occur  as  well  as on any preceding days specified by the
71              reminder's delta.
72
73
74       -l     If you use the -l option in conjunction with the -p option, then
75              Remind outputs additional information for back-end programs such
76              as rem2ps.  This additional information lets the  back-end  pro‐
77              grams  correlate a reminder with the source file and line number
78              that produced it.
79
80       -m     The -m option causes the -c or -p options to produce a  calendar
81              whose first column is Monday rather than Sunday.  (This conforms
82              to the international standard.)
83
84       -v     The -v option makes the output of Remind slightly more  verbose.
85              Currently,  this  causes Remind to echo a bad line in case of an
86              error, and to print a security message if  a  script  tests  the
87              $RunOff system variable.
88
89       -o     The -o option causes Remind to ignore all ONCE directives.
90
91       -t     The   -t   option  causes  Remind  to  trigger  all  non-expired
92              reminders, regardless of the delta supplied for each reminder.
93
94       -h     The -h option ("hush...") suppresses certain warning and  infor‐
95              mation  messages.  In particular, if no reminders are triggered,
96              this mode produces no output.
97
98       -a     The -a option causes Remind not  to  immediately  trigger  timed
99              reminders  that would also be queued.  It also causes Remind not
100              to place timed reminders in a calendar.
101
102       -q     The -q option causes Remind not to  queue  timed  reminders  for
103              later execution.
104
105       -f     The  -f  option  causes  Remind to remain in the foreground when
106              processing queued reminders, rather than  forking  off  a  back‐
107              ground process to handle them.
108
109       -e     The -e option diverts error messages (normally sent to the stan‐
110              dard error stream) to the standard output stream.
111
112       -dchars
113              The -d option enables certain debugging modes.  The chars  spec‐
114              ify which modes to enable:
115
116         e      Echo all input lines
117
118         x      Trace all expression evaluation
119
120         t      Display all trigger date computation
121
122         v      Dump the variable table after execution of the reminder script
123
124         l      Echo lines when displaying error messages
125
126       -g[a|d[a|d[a|d]]]
127              Normally,  reminders  are  issued in the order in which they are
128              encountered in the reminder script.  The -g option cause  Remind
129              to  sort  reminders by date and time prior to issuing them.  The
130              optional a and d characters specify the sort order (ascending or
131              descending)  for  the  date,  time and priority fields.  See the
132              section "Sorting Reminders" for more information.
133
134       -b[n]  Set the time format for the calendar  and  simple-calendar  out‐
135              puts.   N can range from 0 to 2, with the default 0.  A value of
136              0 causes times to be inserted  in  12-hour  (am/pm)  format.   1
137              causes  times  to  be inserted in 24-hour format, and 2 inhibits
138              the automatic insertion of times in the calendar output.
139
140       -x[n]  Sets the iteration limit for the SATISFY clause of  a  REM  com‐
141              mand.  Defaults to 150.
142
143       -kcmd  Instead  of simply printing MSG-type reminders, this causes them
144              to be passed to the specific cmd.  You must use '%s'  where  you
145              want  the body to appear, and may need to enclose this option in
146              quotes.  Note that all shell  characters  in  the  body  of  the
147              reminder  are  escaped  with a backslash, and the entire body of
148              the reminder is passed as a single  argument.   Note  that  this
149              option overrides the -r option and the RUN OFF command.
150
151              As an example, suppose you have an X Window program called xmes‐
152              sage that pops up a window and  displays  its  invocation  argu‐
153              ments.  You could use:
154
155                        remind '-kxmessage %s &' ...
156
157              to have all of your MSG-type reminders processed using xmessage.
158
159              A  word of warning:  It is very easy to spawn dozens of xmessage
160              processes with the above technique.  So be very careful.   Also,
161              the  cmd is passed as an argument to sprintf().  If you use for‐
162              matting directives other than %s, or use more than one %s direc‐
163              tive,  there's a good chance that you'll crash Remind.  Finally,
164              because all shell and whitespace  characters  are  escaped,  the
165              program  you execute with the -k option must be prepared to han‐
166              dle the entire message as a single argument.
167
168       -z[n]  Runs Remind in the daemon mode.  If n is supplied, it  specifies
169              how  often  (in  minutes)  Remind should wake up to check if the
170              reminder script has been changed.  N  defaults  to  5,  and  can
171              range  from  5  to  60.  Note that the use of the -z option also
172              enables the -f option.
173
174              If you supply the option -z0, Remind  runs  in  a  special  mode
175              called  server  mode.   This  is  documented in the tkremind man
176              page; see tkremind(1).
177
178       -uname Runs Remind with the uid and gid of the user specified by  name.
179              The  option  changes  the uid and gid as described, and sets the
180              environment variables HOME, SHELL and USER to  the  home  direc‐
181              tory, shell, and user name, respectively, of the specified user.
182              LOGNAME is also set to the specified user name.  This option  is
183              meant for use in shell scripts that mail reminders to all users.
184              Note that as of Remind 3.00.17, using -u implies -r --  the  RUN
185              directive and shell() functions are disabled.
186
187              Non-root  users  can  also  use the -u option.  However, in this
188              case, it only changes the  environment  variables  as  described
189              above.  It does not change the effective uid or gid.
190
191       -y     Causes  Remind to synthesize a tag for any reminder that lacks a
192              TAG clause.
193
194       -ivar=expr
195              Sets the value of the specified var to expr, and preserves  var.
196              Expr  can be any valid Remind expression.  See the section "Ini‐
197              tializing Variables on the Command Line" for more details.
198
199       If you supply a date on the command line, it must consist of day  month
200       year,  where  day  is the day of the month, month is at least the first
201       three letters of the English name of the month, and year is a year (all
202       4  digits)  from  1990 to about 2075.  You can leave out the day, which
203       then defaults to 1.
204
205       If you do supply a date on the  command  line,  then  Remind  uses  it,
206       rather  than  the  actual  system date, as its notion of "today."  This
207       lets you create calendars for future months, or test to  see  how  your
208       reminders will be triggered in the future.  Similarly, you can supply a
209       time (in 24-hour format -- for example, 17:15) to set  Remind's  notion
210       of  "now"  to  a particular time.  Supplying a time on the command line
211       also implicitly enables the -q option and disables the -z option.
212
213       In addition, you can supply a repeat  parameter,  which  has  the  form
214       *num.  This causes Remind to be run num times, with the date increment‐
215       ing on each iteration.  You may have to enclose the parameter in quotes
216       to  avoid  shell expansion.  See the subsection "Repeated Execution" in
217       the section "Calendar Mode" for more information.
218

REMINDER FILES

220       Remind uses scripts to control its operation.  You  can  use  any  text
221       editor capable of creating plain ASCII files to create a Remind script.
222       The commands inside a script can range from the very simple and  almost
223       immediately understandable:
224
225            REM 6 Jan MSG David's birthday
226
227       to the baroque and obscure:
228
229            REM [trigger(date(thisyear, 1, 1) + 180)] ++5 OMIT \
230            sat sun BEFORE MSG [ord(thisyear-1980)] payment due %b!
231
232       A  reminder file consists of commands, with one command per line.  Sev‐
233       eral lines can be continued using the backslash character,  as  in  the
234       above example.  In this case, all of the concatenated lines are treated
235       as a single line by Remind.  Note  that  if  an  error  occurs,  Remind
236       reports the line number of the last line of a continued line.
237
238       Remind  ignores  blank  lines,  and lines beginning with the '#' or ';'
239       characters.  You can use the semicolon as a comment  character  if  you
240       wish  to pass a Remind script through the C pre-processor, which inter‐
241       prets the '#' character as the start of a pre-processing directive.
242
243       Remind is not case sensitive; you can  generally  use  any  mixture  of
244       upper- or lower-case for commands, parameters, invocation options, etc.
245

THE REM COMMAND

247       The  most powerful command in a Remind script is the REM command.  This
248       command is responsible for issuing reminders.  Its syntax is:
249
250              REM [ONCE] [date_spec] [back] [delta] [repeat]  [PRIORITY  prio]
251              [SKIP | BEFORE | AFTER] [OMIT omit_list] [AT time [tdelta] [tre‐
252              peat]]  [SCHED  sched_function]  [WARN   warn_function]   [UNTIL
253              expiry_date]  [SCANFROM  scan_date  | FROM start_date] [DURATION
254              duration] [TAG tag] <MSG | MSF | RUN | CAL | SATISFY  |  SPECIAL
255              special | PS | PSFILE> body
256
257       The parts of the REM command can be specified in any order, except that
258       the body must come immediately after the MSG, RUN, CAL, PS,  PSFILE  or
259       SATISFY keyword.
260
261       The  REM token is optional, providing that the remainder of the command
262       cannot be mistaken for another Remind command such as OMIT or RUN.  The
263       portion  of  the  REM  command  before the MSG, MSF RUN, CAL or SATISFY
264       clause is called a trigger.
265
266       MSG, MSF, RUN, CAL, SPECIAL, PS and PSFILE
267
268       These keywords denote the type of the reminder.  (SATISFY is more  com‐
269       plicated  and  will  be explained later.)  A MSG-type reminder normally
270       prints a message to the standard output, after passing the body through
271       a  special substitution filter, described in the section "The Substitu‐
272       tion Filter."  However, if you have used the  -k  command-line  option,
273       then  MSG-type  reminders  are passed to the appropriate program.  Note
274       that the options -c, -s, -p and -n disable the -k option.
275
276       Note that you can omit the reminder type, in which case it defaults  to
277       MSG.  So you can write:
278
279            6 January David's Birthday
280
281       although this is not recommended.
282
283       The  MSF keyword is almost the same as the MSG keyword, except that the
284       reminder is formatted to fit into a paragraph-like format.  Three  sys‐
285       tem  variables  control the formatting of MSF-type reminders - they are
286       $FirstIndent, $SubsIndent and $FormWidth.  They are  discussed  in  the
287       section "System Variables."  The MSF keyword causes the spacing of your
288       reminder to be altered - extra spaces are discarded, and two spaces are
289       placed  after  periods and other characters, as specified by the system
290       variables $EndSent and $EndSentIg.   Note  that  if  the  body  of  the
291       reminder   includes  newline  characters  (placed  there  with  the  %_
292       sequence), then the newlines are treated as the beginnings of new para‐
293       graphs,  and  the  $FirstIndent  indentation is used for the next line.
294       You can use two consecutive newlines to have spaced paragraphs  emitted
295       from a single reminder body.
296
297       A  RUN-type reminder also passes the body through the substitution fil‐
298       ter, but then executes the result as  a  system  command.   A  CAL-type
299       reminder  is  used  only to place entries in the calendar produced when
300       Remind is run with the -c, -s or -p options.
301
302       A PS or PSFILE-type reminder is used to pass PostScript  code  directly
303       to  the  printer when producing PostScript calendars.  This can be used
304       to shade certain calendar entries (see the psshade() function), include
305       graphics in the calendar, or almost any other purpose you can think of.
306       You should not use these types of reminders unless you  are  an  expert
307       PostScript  programmer.  The PS and PSFILE reminders are ignored unless
308       Remind is run with the -p option.  See the section  "More  about  Post‐
309       Script" for more details.
310
311       A  SPECIAL-type reminder is used to pass "out-of-band" information from
312       Remind to a calendar-producing back-end.  It should be  followed  by  a
313       word  indicating  the type of special data being passed.  The type of a
314       special reminder depends on the back-end.   For  the  Rem2PS  back-end,
315       SPECIAL  PostScript  is  equivalent  to a PS-type reminder, and SPECIAL
316       PSFile is equivalent to a PSFILE-type reminder.  The body of a  SPECIAL
317       reminder is obviously dependent upon the back-end.
318
319       DATE SPECIFICATIONS
320
321       A  date_spec  consists of zero to four parts.  These parts are day (day
322       of month), month (month name), year and weekday.  Month and weekday are
323       the  English  names  of  months and weekdays.  At least the first three
324       characters must be used.  The following are  examples  of  the  various
325       parts of a date_spec:
326
327       day:   1, 22, 31, 14, 3
328
329       month: JANUARY, feb, March, ApR, may, Aug
330
331       year:  1990,  1993, 2030, 95 (interpreted as 1995).  The year can range
332              from 1990 to 2075.
333
334       weekday:
335              Monday, tue, Wed, THU, Friday, saturday, sundAy
336
337       Note that there can be several weekday components separated  by  spaces
338       in a date_spec.
339
340       INTERPRETATION OF DATE SPECIFICATIONS
341
342       The following examples show how date specifications are interpreted.
343
344       1.  Null date specification - the reminder is triggered every day.  The
345       trigger date for a specific run is simply the current system date.
346
347       2. Only day present.  The reminder is triggered on the specified day of
348       each  month.  The trigger date for a particular run is the closest such
349       day to the current system date.  For example:
350            REM 1 MSG First of every month.
351            REM 31 MSG 31st of every month that has 31 days.
352
353       3. Only month present.  The reminder is  triggered  every  day  of  the
354       specified month.  Example:
355            REM Feb MSG Every day in February
356
357       4.  day and month present.  Examples:
358            REM 6 Jan MSG Every 6th of January
359            REM Feb 29 MSG Every 29th of February
360
361       5.  Only year present. Example:
362            REM 1991 MSG Every day in 1991
363
364       6.  year and day present.  Examples:
365            REM 1 1990 MSG 1st of every month in 1990
366            REM 1992 23 MSG 23rd of every month in 1992
367
368       7.  year and month present.  Examples:
369            REM Feb 1991 MSG Every day in Feb 1991
370            REM 1992 September MSG Every day in Sept 1992
371
372       8.  year, month and day present.  Examples:
373            REM 8 Jan 1991 MSG 8th January 1991.
374            REM 1992 March 9 MSG 9th March 1992.
375
376       9.  weekday only.  Examples:
377            REM Sat MSG Every Saturday
378            REM Mon Tue Wed Thu Fri MSG Every working day
379            REM Monday Wednesday MSG Every Monday and Wednesday
380
381       10.  weekday and day present.  Examples:
382            REM Sat 1 MSG First Saturday of every month
383            REM Mon Tue Wed Thu Fri 15 \
384                 MSG 1st working day after 15th of every month
385
386       11.  weekday and month present.  Examples:
387            REM Mon March MSG Every Monday in March
388            REM Mon Tue Wed Thu Fri Feb MSG Every working day in February
389
390       12.  weekday, month and day present.  Examples:
391            REM Mon 1 March MSG First Monday in March
392            REM Sat Sun 15 July MSG First Sat or Sun on or after 15 July
393
394       13.  weekday and year present.  Example:
395            REM Sat Sun 1991 MSG Every Saturday and Sunday in 1991
396
397       14.  weekday, day and year present.  Examples:
398            REM Mon 15 1990 MSG 1st Mon after 15th of every month in 1990
399            REM Mon Tue Wed Thu Fri 1 1990 \
400                 MSG 1st working day of every month in 1990
401
402       15.  weekday, month and year present.  Example:
403            REM Mon Wed 1991 Feb MSG Every Mon and Wed in Feb 1991.
404
405       16.  weekday, day, month and year present.  Example:
406            REM Mon Tue Wed Thu Fri 28 Oct 1990 \
407                 MSG 1st working day on or after 28 October 1990.
408
409       Note  that  when both weekday and day are specified, Remind chooses the
410       first date on or after the specified day that also satisfies the  week‐
411       day constraint.  It does this by picking the first date on or after the
412       specified day that is listed in the list of weekdays.  Thus, a reminder
413       like:
414
415            REM Mon Tue 28 Oct 1990 MSG Hi
416
417       would  be  issued  only  on  Monday, 29 October, 1990.  It would not be
418       issued on Tuesday, 30 October, 1990, since the 29th is the  first  date
419       to satisfy the weekday constraints.
420
421       BACKWARD SCANNING
422
423       Sometimes,  it  is necessary to specify a date as being a set amount of
424       time before another date.  For example, the  last  Monday  in  a  given
425       month  is computed as the first Monday in the next month, minus 7 days.
426       The back specification in the reminder is used in this case:
427
428            REM Mon 1 -7 MSG Last Monday of every month.
429
430       A back is specified with one or two  dashes  followed  by  an  integer.
431       This  causes Remind to move "backwards" from what would normally be the
432       trigger date.  The difference between --7 and -7 will be explained when
433       the OMIT keyword is described.
434
435       ADVANCE WARNING
436
437       For some reminders, it is appropriate to receive advance warning of the
438       event.  For example, you may wish to be reminded of someone's  birthday
439       several days in advance.  The delta portion of the REM command achieves
440       this.  It is specified as one or two "+" signs followed by a number  n.
441       Again,  the difference between the "+" and "++" forms will be explained
442       under the OMIT keyword.  Remind will trigger the reminder  on  computed
443       trigger  date, as well as on each of the n days before the event.  Here
444       are some examples:
445
446            REM 6 Jan +5 MSG Remind me of birthday 5 days in advance.
447
448       The above example would be triggered every 6th of January, as  well  as
449       the 1st through 5th of January.
450
451       PERIODIC REMINDERS
452
453       We  have  already  seen  some  built-in mechanisms for certain types of
454       periodic reminders.  For example, an event  occurring  every  Wednesday
455       could be specified as:
456
457            REM Wed MSG Event!
458
459       However,  events  that  do  not repeat daily, weekly, monthly or yearly
460       require another approach.  The repeat  component  of  the  REM  command
461       fills  this need.  To use it, you must completely specify a date (year,
462       month and day, and optionally weekday.)  The  repeat  component  is  an
463       asterisk followed by a number specifying the repetition period in days.
464
465       For example, suppose you get paid every second Wednesday, and your last
466       payday was Wednesday, 28 October, 1992.  You can use:
467
468            REM 28 Oct 1992 *14 MSG Payday
469
470       This issues the reminder every 14 days, starting  from  the  calculated
471       trigger  date.  You can use delta and back with repeat.  Note, however,
472       that the back is used only to compute the initial trigger date;  there‐
473       after,  the  reminder repeats with the specified period.  Similarly, if
474       you specify a weekday, it is used only to calculate the  initial  date,
475       and does not affect the repetition period.
476
477       SCANFROM and FROM
478
479       The  SCANFROM  and  FROM  keywords  are for advanced Remind programmers
480       only, and will be explained in the section "Details about Trigger  Com‐
481       putation" near the end of this manual.  Note that SCANFROM is available
482       only in versions of Remind from 03.00.04 up.  FROM  is  available  only
483       from 03.01.00 and later.
484
485       PRIORITY
486
487       The  PRIORITY  keyword must be followed by a number from 0 to 9999.  It
488       is used in calendar mode and when sorting reminders.  If two  reminders
489       have  the same trigger date and time, then they are sorted by priority.
490       If the PRIORITY keyword is not supplied, a default priority of 5000  is
491       used.   (This  default  can be changed by adjusting the system variable
492       $DefaultPrio.  See the section "System  Variables"  for  more  informa‐
493       tion.)
494
495       EXPIRY DATES
496
497       Some  reminders  should  be issued periodically for a certain time, but
498       then expire.  For example, suppose you have a class every  Friday,  and
499       that your last class is on 11 December 1992.  You can use:
500
501            REM Fri UNTIL 11 Dec 1992 MSG Class today.
502
503       Another  example:   Suppose  you  have  jury duty from 30 November 1992
504       until 4 December 1992.  The following reminder will issue  the  message
505       every day of your jury duty, as well as 2 days ahead of time:
506
507            REM 30 Nov 1992 *1 +2 UNTIL 4 Dec 1992 MSG Jury duty
508
509       Note that the repeat of *1 is necessary; without it, the reminder would
510       be issued only on 30 November (and the two days preceding.)
511
512       THE ONCE KEYWORD
513
514       Sometimes, it is necessary to ensure that reminders are run  only  once
515       on  a  given  day.   For  example,  if you have a reminder that makes a
516       backup of your files every Friday:
517
518            REM Fri RUN do_backup
519
520       (Here, do_backup is assumed to be a program or shell script  that  does
521       the work.)  If you run Remind from your .login script, for example, and
522       log in several times per day, the do_backup program will  be  run  each
523       time  you  log  in.   If,  however,  you  use  the  ONCE keyword in the
524       reminder, the Remind checks  the  last  access  date  of  the  reminder
525       script.   If it is the same as the current date, Remind assumes that it
526       has already been run, and will not issue reminders containing the  ONCE
527       keyword.
528
529       Note  that  if  you  view or edit your reminder script, the last access
530       date will be updated, and the ONCE keyword will not  operate  properly.
531       If  you  start Remind with the -o option, then the ONCE keyword will be
532       ignored.
533
534       LOCALLY OMITTING WEEKDAYS
535
536       The OMIT portion of the REM command is used to "omit" certain days when
537       counting  the  delta  or  back.  It is specified using the keyword OMIT
538       followed by a list of weekdays.  Its action is  best  illustrated  with
539       examples:
540
541            REM 1 +1 OMIT Sat Sun MSG Important Event
542
543       This  reminder  is  normally  triggered on the first of every month, as
544       well as the day preceding it.  However, if the first of the month falls
545       on a Sunday or Monday, then the reminder is triggered starting from the
546       previous Friday.  This is because the delta of +1 does not count Satur‐
547       day  or Sunday when it counts backwards from the trigger date to deter‐
548       mine how much advance warning to give.
549
550       Contrast this with the use of "++1" in  the  above  command.   In  this
551       case,  the reminder is triggered on the first of each month, as well as
552       the day preceding it.  The omitted days are counted.
553
554            REM 1 -1 OMIT Sat Sun MSG Last working day of month
555
556       Again, in the above example, the back of -1 normally causes the trigger
557       date  to  be  the  last day of the month.  However, because of the OMIT
558       clause, if the first of the month falls on  a  Sunday  or  Monday,  the
559       trigger  date  is  moved backwards past the weekend to Friday.  (If you
560       have globally omitted holidays, the reminder will be  moved  back  past
561       them, also.  See "The OMIT command" for more details.)
562
563       By comparison, if we had used "--1", the reminder would be triggered on
564       the last day of the month, regardless of the OMIT.
565
566       TIMED REMINDERS
567
568       Timed reminders are those that have an AT keyword followed  by  a  time
569       and optional tdelta and trepeat.  The time must be specified in 24-hour
570       format, with 0:00 representing midnight, 12:00 representing  noon,  and
571       23:59  representing one minute to midnight.  You can use either a colon
572       or a period to separate the hours from the minutes.  That is, 13:39 and
573       13.39 are equivalent.
574
575       Remind  treats  timed  reminders  specially.  If the trigger date for a
576       timed reminder is the same as the current system date, the reminder  is
577       queued  for  later activation.  When Remind has finished processing the
578       reminder file, it puts itself in the background,  and  activates  timed
579       reminders when the system time reached the specified time.
580
581
582       If the trigger date is not the same as the system date, the reminder is
583       not queued.
584
585       For example, the following reminder, triggered every working day,  will
586       emit a message telling you to leave at 5:00pm:
587
588            REM Mon Tue Wed Thu Fri AT 17:00 MSG Time to leave!
589
590       The  following reminder will be triggered on Thursdays and Fridays, but
591       will only be queued on Fridays:
592
593            REM Fri ++1 AT 13:00 MSG Lunch at 1pm Friday.
594
595       The tdelta and trepeat have the same form as a repeat  and  delta,  but
596       are specified in minutes.  For example, this reminder will be triggered
597       at 12:00pm as well as 45 minutes before:
598
599            REM AT 12:00 +45 MSG Example
600
601       The following will be issued starting at 10:45, every half  hour  until
602       11:45, and again at noon.
603
604            REM AT 12:00 +75 *30 MSG Example2
605
606       The  "+75" means that the reminder is issued starting 75 minutes before
607       noon; in other words, at 10:45.  The *30 specifies that the reminder is
608       subsequently  to be issued every 30 minutes.  Note that the reminder is
609       always issued at the specified time, even if the tdelta is not a multi‐
610       ple  of  the  trepeat.   So  the  above  example  is issued at 10:45am,
611       11:15am, 11:45am, and 12:00pm.  Note that in  the  time  specification,
612       there is no distinction between the "+" and "++" forms of tdelta.
613
614       Normally,  Remind  will  issue  timed  reminders  as  it  processes the
615       reminder script, as well as queuing them for later.  If you do not want
616       Remind  to  issue the reminders when processing the script, but only to
617       queue them for later, use the -a command-line option.  If  you  do  not
618       want reminders to be queued for later, use the -q command-line option.
619
620       Normally, Remind forks a background process to handle queued reminders.
621       If you want Remind to remain in the foreground, use the -f command-line
622       option.   This  is  useful, for example, in .xinitrc scripts, where you
623       can use the command:
624
625            remind -fa myreminders &
626
627       This ensures that when  you  exit  X-Windows,  the  Remind  process  is
628       killed.
629
630       WARNING ABOUT TIMED REMINDERS
631
632       Note:  If you use user-defined functions or variables (described later)
633       in the bodies of timed reminders, then when  the  timed  reminders  are
634       activated,  the  variables and functions have the definitions that were
635       in effect at the end of the reminder script.  These definitions may not
636       necessarily  be  those that were in effect at the time the reminder was
637       queued.
638
639       THE SCHED AND WARN KEYWORDS
640
641       The SCHED keyword allows more precise control over  the  triggering  of
642       timed  reminders,  and the WARN keyword allows precise control over the
643       advance triggering of all types of reminders.  However, discussion must
644       be  deferred  until  after  expressions  and user-defined functions are
645       explained.  See the subsection "Precise Scheduling" further on.
646
647       TAG AND DURATION
648
649       The TAG keyword lets you "tag" certain  reminders.   This  facility  is
650       used by certain back-ends or systems built around Remind, such as TkRe‐
651       mind.  These back-ends have specific rules about tags; you  should  not
652       use  the  TAG keyword yourself, or your script will interact badly with
653       back-ends.
654
655       The TAG keyword is followed by a tag consisting of up to 48 characters.
656
657       If you supply the -y option to Remind, then any reminder that  lacks  a
658       TAG  will  have  one  synthesized.  The synthesized tag consists of the
659       characters "__syn__" followed by the hexadecimal representation of  the
660       MD5  sum  of  the  REM command line.  This lets you give a more-or-less
661       unique identifier to each distinct REM command.
662
663       The DURATION keyword makes sense only for timed reminders; it specifies
664       the  duration  of an event.  Currently, this is not used, but it may be
665       used in future by back-ends or scheduling systems built around  Remind.
666       For  example,  if  you have a 90-minute meeting starting at 1:00pm, you
667       could use:
668
669            REM 5 March 1999 AT 13:00 DURATION 1:30 MSG Meeting
670
671       Note that duration is specified in hours and minutes.
672

THE SUBSTITUTION FILTER

674       Before being processed, the body of a REM command is passed  through  a
675       substitution filter.  The filter scans for sequences "%x" (where "x" is
676       any letter and certain other characters) and performs substitutions  as
677       shown below.  (All dates refer to the trigger date of the reminder.)
678
679       %a     is replaced with "on weekday, day month, year"
680              For example, consider the reminder:
681
682              REM 18 Oct 1990 +4 MSG Meeting with Bob %a.
683
684              On  16  October 1990, it would print "Meeting with Bob on Thurs‐
685              day, 18 October, 1990."
686
687              On 17 October 1990, it would print "Meeting with Bob tomorrow."
688
689              On 18 October 1990, it would print "Meeting with Bob today."
690
691       %b     is replaced with "in diff day's time" where diff is  the  actual
692              number  of  days  between the current date and the trigger date.
693              (OMITs have no effect.)
694              For example, consider:
695
696              REM 18 Oct 1990 +4 MSG Meeting with Bob %b.
697
698              On 16 October 1990, it would print "Meeting with Bob in 2  days'
699              time."
700
701              On 17 October 1990, it would print "Meeting with Bob tomorrow."
702
703              On 18 October 1990, it would print "Meeting with Bob today."
704
705       %c     is replaced with "on weekday"
706              Example: REM 18 Oct 1990 +4 MSG Meeting with Bob %c.
707
708              On  16  October 1990, it would print "Meeting with Bob on Thurs‐
709              day."
710
711              On 17 October 1990, it would print "Meeting with Bob tomorrow."
712
713              On 18 October 1990, it would print "Meeting with Bob today."
714
715       %d     is replaced with "day", the day of the month.
716
717       %e     is replaced with "on dd-mm-yyyy"
718
719       %f     is replaced with "on mm-dd-yyyy"
720
721       %g     is replaced with "on weekday, day month"
722
723       %h     is replaced with "on dd-mm"
724
725       %i     is replaced with "on mm-dd"
726
727       %j     is replaced with "on weekday, month  day-th,  year"   This  form
728              appends  the  characters  "st", "nd", "rd" or "th" to the day of
729              the month, as appropriate.
730
731       %k     is replaced with "on weekday, month day-th"
732
733       %l     is replaced with "on yyyy-mm-dd"
734
735       %m     is replaced with "month", the name of the month.
736
737       %n     is replaced with the number (1 to 12) of the month.
738
739       %o     is replaced with " (today)" if and only if  the  current  system
740              date is the same as the date being used by Remind as the current
741              date.  Recall that you can specify a date for Remind to  use  on
742              the  command line.  This substitution is not generally useful in
743              a REM command, but is useful in a  BANNER  command.   (See  "The
744              BANNER Command.")
745
746       %p     is  replaced  with  "s" if the diff between the current date and
747              the trigger date is not  1.   You  can  use  this  to  construct
748              reminders like:
749              REM 1 Jan +4 MSG %x day%p to go before New Year!
750
751       %q     is  replaced  with "'s" if the diff between the trigger date and
752              the current date is 1.  Otherwise,  it  is  replaced  with  "s'"
753              This can be used as follows:
754              REM 1 Jan +4 MSG New Year in %x day%q time!
755
756       %r     is  replaced  with the day of the month (01 to 31) padded with a
757              leading zero if needed to pad to two digits.
758
759       %s     is replaced with "st", "nd", "rd" or "th" depending on  the  day
760              of the month.
761
762       %t     is  replaced  with  the number of the month (01 to 12) padded to
763              two digits with a leading zero.
764
765       %u     is replaced with "on weekday, day-th month, year"  This is simi‐
766              lar  to  %a except that "st", "nd", "rd" or "th" is added to the
767              day as appropriate.
768
769       %v     is replaced with "on weekday, day-th month"
770
771       %w     is replaced with "weekday", the name of the day of the week.
772
773       %x     is replaced with the diff between the current date and the trig‐
774              ger  date.   The  diff  is  defined as the actual number of days
775              between these two dates; OMITs are not  counted.   (Strict  date
776              subtraction is performed.)
777
778       %y     is replaced with "year", the year of the trigger date.
779
780       %z     is replaced with "yy", the last two digits of the year.
781
782       %_     (percent-underscore)  is  replaced  with a newline.  You can use
783              this to achieve multi-line reminders.
784
785       %1     is replaced with "now", "m minutes from now", "m  minutes  ago",
786              "h  hours  from now", "h hours ago", "h hours and m minutes from
787              now" or "h hours and m minutes ago", as appropriate for a  timed
788              reminder.   Note  that  unless  you specify the -a option, timed
789              reminders will be triggered like normal reminders,  and  thus  a
790              timed  reminder  that  occurred  earlier in the day may be trig‐
791              gered.  This causes the need for the "...ago" forms.
792
793       %2     is replaced with "at hh:mmam" or "..pm" depending on the AT time
794              of the reminder.
795
796       %3     is replaced with "at hh:mm" in 24-hour format.
797
798       %4     is  replaced with "mm" where mm is the number of minutes between
799              "now" and the time specified by AT.  If the AT time  is  earlier
800              than the current time, then the result is negative.
801
802       %5     is replaced with "ma" where ma is the absolute value of the num‐
803              ber produced by %4.
804
805       %6     is replaced with "ago" or "from now", depending on the relation‐
806              ship between the AT time and the current time.
807
808       %7     is replaced with the number of hours between the AT time and the
809              current time.  It is always non-negative.
810
811       %8     is replaced with the number of minutes between the AT  time  and
812              the current time, after the hours (%7) have been subtracted out.
813              This is a number ranging from 0 to 59.
814
815       %9     is replaced with "s" if the value produced by %8 is not 1.
816
817       %0     is replaced with "s" if the value produced by %7 is not 1.
818
819       %!     is replaced with "is" if the current time is before the AT time,
820              or "was" if it is after.
821
822       %@     is similar to %2 but displays the current time.
823
824       %#     is similar to %3 but displays the current time.
825
826       %"     (percent-doublequote - ") is removed.  This sequence is not used
827              by the substitution filter, but is used  to  tell  Remind  which
828              text to include in a calendar entry when the -c, -s or -p option
829              is chosen.  See "Calendar Mode"
830
831       Notes:
832
833       o      Remind normally prints a blank line after each reminder; if  the
834              last  character  of  the body is "%", the blank line will not be
835              printed.
836
837       o      Substitutions a, b, c, e, f, g, h, i, j, k, l, u and v  all  are
838              replaced  with  "today"  if  the current date equals the trigger
839              date, or "tomorrow" if the trigger date is  one  day  after  the
840              current  date.   Thus,  they  are  not the same as substitutions
841              built up from the simpler %w, %y, etc.  sequences.
842
843       o      Any of the substitutions dealing with time (0 through 9 and '!')
844              produce  undefined  results  if used in a reminder that does not
845              have an AT keyword.  Also, if a reminder has a delta and may  be
846              triggered  on  several  days,  the time substitutions ignore the
847              date.  Thus, the %1 substitution may report that a meeting is in
848              15  minutes,  for  example, even though it may only be in 2 days
849              time, because a delta has triggered the reminder.  It is  recom‐
850              mended  that  you  use  the  time  substitutions  only  in timed
851              reminders with no delta that are designed to be queued for timed
852              activation.
853
854       o      Capital  letters  can  be  used in the substitution sequence, in
855              which case the first character of the substituted string is cap‐
856              italized (if it is normally a lower-case letter.)
857
858       o      All other characters following a "%" sign are simply copied.  In
859              particular, to get a "%" sign out, use "%%"  in  the  body.   To
860              start  the  body  of  a  reminder  with a space, use "% ", since
861              Remind normally scans for the first non-space character after  a
862              MSG, CAL or RUN token.
863

THE OMIT COMMAND

865       In addition to being a keyword in the REM command, OMIT is a command in
866       its own right.  Its syntax is:
867
868              OMIT day month [year]
869
870       The OMIT command is used to "globally" omit certain days (usually holi‐
871       days).   These  globally-omitted  days  are  skipped by the "-" and "+"
872       forms of back and delta.  Some examples:
873
874            OMIT 1 Jan
875            OMIT 7 Sep 1992
876
877       The first example specifies a holiday that occurs on the same date each
878       year  -  New  Year's  Day.  The second example specifies a holiday that
879       changes each year - Labour Day.  For these types of holidays, you  must
880       create  an  OMIT  command for each year.  (Later, in the description of
881       expressions and some of the more advanced features of Remind, you  will
882       see how to automate this for some cases.)
883
884       For convenience, you can use a delta and MSG or RUN keyword in the OMIT
885       command.  The following sequences are exactly equivalent:
886
887            OMIT 1 Jan
888            REM 1 Jan +4 MSG New year's day is %b!
889
890            and
891
892            OMIT 1 Jan +4 MSG New year's day is %b!
893
894       THE BEFORE, AFTER AND SKIP KEYWORDS
895
896       Normally, days that are omitted, whether by a global  OMIT  command  or
897       the  local OMIT keyword in a REM statement, only affect the counting of
898       the -back or the +delta.  For example, suppose you have a meeting every
899       Wednesday.  Suppose, too, that you have indicated 11 Nov as a holiday:
900
901            OMIT 11 Nov +4 MSG Remembrance Day
902            REM Wed +1 MSG Code meeting %b.
903
904       The  above sequence will issue a reminder about a meeting for 11 Novem‐
905       ber 1992, which is a Wednesday.  This is probably incorrect.  There are
906       three options:
907
908       BEFORE This  keyword  moves  the  reminder  to before any omitted days.
909              Thus, in the above example, use of BEFORE would cause the  meet‐
910              ing reminder to be triggered on Tuesday, 10 November 1992.
911
912       AFTER  This  keyword  moves the reminder to after any omitted days.  In
913              the above example, the meeting reminder would  be  triggered  on
914              Thursday, 12 November 1992.
915
916       SKIP   This keyword causes the reminder to be skipped completely on any
917              omitted days.  Thus, in the above example,  the  reminder  would
918              not  be  triggered  on  11  November 1992.  However, it would be
919              triggered as usual on the following Wednesday, 18 November 1992.
920
921       The BEFORE and AFTER keywords move the trigger date of  a  reminder  to
922       before  or  after  a  block of omitted days, respectively.  Suppose you
923       normally run a backup on the first day of the month.  However,  if  the
924       first  day  of the month is a weekend or holiday, you run the backup on
925       the first working day following the weekend or holiday.  You could use:
926
927            REM 1 OMIT Sat Sun AFTER RUN do_backup
928
929       Let's examine how the trigger date is computed.  The  1  specifies  the
930       first  day  of the month.  The local OMIT keyword causes the AFTER key‐
931       word to move the reminder forward past weekends.   Finally,  the  AFTER
932       keyword  will  keep moving the reminder forward until it has passed any
933       holidays specified with global OMIT commands.
934

THE INCLUDE COMMAND

936       Remind allows you to include other files in your reminder script, simi‐
937       lar to the C preprocessor #include directive.  For example, your system
938       administrator may maintain a file of holidays or system-wide reminders.
939       You can include these in your reminder script as follows:
940
941            INCLUDE /usr/share/remind/holidays
942            INCLUDE /usr/share/remind/reminders
943
944       (The  actual  pathnames  vary  from  system to system - ask your system
945       administrator.)
946
947       INCLUDE files can be nested up to a depth of 8.
948
949       If you specify a filename of "-" in the INCLUDE  command,  Remind  will
950       begin reading from standard input.
951

THE RUN COMMAND

953       If  you include other files in your reminder script, you may not always
954       entirely trust the contents of the other files.  For example, they  may
955       contain  RUN-type  reminders that could be used to access your files or
956       perform undesired actions.  The RUN command can restrict this:  If  you
957       include  the  command  RUN  OFF  in your top-level reminder script, any
958       reminder or expression that would normally execute a system command  is
959       disabled.   RUN  ON  will  re-enable  the execution of system commands.
960       Note that the RUN ON  command  can  only  be  used  in  your  top-level
961       reminder  script; it will not work in any files accessed by the INCLUDE
962       command.  This is to protect you from someone placing a RUN ON  command
963       in  an  included file.  However, the RUN OFF command can be used at top
964       level or in an included file.
965
966       If you run Remind with the -r command-line option,  RUN-type  reminders
967       and  the  shell() function will be disabled, regardless of any RUN com‐
968       mands in the reminder script.  However, any command supplied  with  the
969       -k option will still be executed.
970
971       One  use  of  the  RUN command is to provide a secure interface between
972       Remind and the Elm mail system.  The Elm system can automatically  scan
973       incoming  mail for reminder or calendar entries, and place them in your
974       calendar file.  To use this feature, you should set the calendar  file‐
975       name  option under Elm to be something like "~/.reminders.in", not your
976       main reminder file!  This is so that any RUN ON commands mailed to  you
977       can never be activated.
978
979       Then,  you can use the Elm scan message for calendar entries command to
980       place reminders prefaced by "->"  into  .reminders.in.   In  your  main
981       .reminders file, include the following lines:
982
983            RUN OFF   # Disable RUN
984            INCLUDE .reminders.in
985            RUN ON    # Re-enable RUN
986
987       In  addition,  Remind  contains a few other security features.  It will
988       not read a file that is group- or world-writable.  It will not run set-
989       uid.   If  it  reads  a file you don't own, it will disable RUN and the
990       shell() function.  And if it is run as root, it will  only  read  files
991       owned by root.
992

THE BANNER COMMAND

994       When Remind first issues a reminder, it prints a message like this:
995
996            Reminders for Friday, 30th October, 1992 (today):
997
998       (The  banner is not printed if any of the calendar-producing options is
999       used, or if the -k option is used.)
1000
1001       The BANNER command lets you change the format.  It should appear before
1002       any REM commands.  The format is:
1003
1004              BANNER format
1005
1006       The  format  is  similar  to  the  body of a REM command.  It is passed
1007       through the substitution filter, with an implicit trigger of  the  cur‐
1008       rent system date.  Thus, the default banner is equivalent to:
1009
1010            BANNER Reminders for %w, %d%s %m, %y%o:
1011
1012       You can disable the banner completely with BANNER %.  Or you can create
1013       a custom banner:
1014
1015            BANNER Hi - here are your reminders for %y-%t-%r:
1016

CONTROLLING THE OMIT CONTEXT

1018       Sometimes, it is necessary to temporarily change the global OMITs  that
1019       are in force for a few reminders.  Three commands allow you to do this:
1020
1021       PUSH-OMIT-CONTEXT
1022              This  command  saves  the  current  global  OMITs on an internal
1023              stack.
1024
1025       CLEAR-OMIT-CONTEXT
1026              This command clears all of the global OMITs,  starting  you  off
1027              with a "clean slate."
1028
1029       POP-OMIT-CONTEXT
1030              This  command  restores  the global OMITs that were saved by the
1031              most recent PUSH-OMIT-CONTEXT.
1032
1033       For example, suppose you have a block of reminders that require a clear
1034       OMIT  context,  and that they also introduce unwanted global OMITs that
1035       could interfere with later reminders.   You  could  use  the  following
1036       fragment:
1037
1038            PUSH-OMIT-CONTEXT   # Save the current context
1039            CLEAR-OMIT-CONTEXT  # Clean the slate
1040            # Block of reminders goes here
1041            POP-OMIT-CONTEXT    # Restore the saved omit context
1042

EXPRESSIONS

1044       In  certain contexts, to be described later, Remind will accept expres‐
1045       sions for evaluation.  Remind expressions resemble C  expressions,  but
1046       operate on different types of objects.
1047
1048       DATA TYPES
1049
1050       Remind expressions operate on five types of objects:
1051
1052       INT    The  INT data type consists of the integers representable in one
1053              machine word.  The INT data type  corresponds  to  the  C  "int"
1054              type.
1055
1056       STRING The  STRING  data type consists of strings of characters.  It is
1057              somewhat comparable to a C character  array,  but  more  closely
1058              resembles the string type in BASIC.
1059
1060       TIME   The  TIME data type consists of times of the day.  The TIME data
1061              type is internally stored as an integer representing the  number
1062              of minutes since midnight.
1063
1064       DATE   The  DATE  data  type  consists  of  dates (later than 1 January
1065              1990.)  Internally, DATE objects are stored  as  the  number  of
1066              days since 1 January 1990.
1067
1068       DATETIME
1069              The  DATETIME  data  type  consists of a date and time together.
1070              Internally, DATETIME objects are stored as the number of minutes
1071              since  midnight,  1  January  1990.  You can think of a DATETIME
1072              object as being the combination of DATE and TIME parts.
1073
1074       CONSTANTS
1075
1076       The following examples illustrate constants in Remind expressions:
1077
1078       INT constants
1079              12, 36, -10, 0, 1209
1080
1081       STRING constants
1082              "Hello there", "This is a test", "\n\gosd\w", ""
1083
1084              Note that the empty string is represented by "", and that  back‐
1085              slashes  in  a  string are not interpreted specially, as in they
1086              are in C.
1087
1088       TIME constants
1089              12:33, 0:01, 14:15, 16:42, 12.16, 13.00, 1.11
1090
1091              Note that TIME constants are written in 24-hour format.   Either
1092              the period or colon can be used to separate the minutes from the
1093              hours.  However, Remind will  consistently  output  times  using
1094              only  one  separator character.  (The output separator character
1095              is chosen at compile-time.)
1096
1097       DATE constants
1098              DATE constants are expressed as  'yyyy/mm/dd'  or  'yyyy-mm-dd',
1099              and the single quotes must be supplied.  This distinguishes date
1100              constants from division or subtraction of integers.  Examples:
1101
1102              ´1993/02/22', '1992-12-25', '1999/01/01'
1103
1104              Note that DATE values are printed without the quotes.   Although
1105              either '-' or '/' is accepted as a date separator on input, when
1106              dates are printed, only one will be used.  The choice of whether
1107              to  use '-' or '/' is made at compile-time.  Note also that ver‐
1108              sions of Remind prior to 03.00.01  did  not  support  date  con‐
1109              stants.   In  those  versions,  you  must create dates using the
1110              date() function.  Also, versions prior to 03.00.02 did not  sup‐
1111              port the '-' date separator.
1112
1113       DATETIME constants
1114              DATETIME  constants  are  expressed  similarly to DATE constants
1115              with the addition of an "@HH:MM" part.  For example:
1116
1117              ´2008-04-05@23:11', '1999/02/03@14:06', '2001-04-07@08:30'
1118
1119              DATETIME values are printed without  the  quotes.   Notes  about
1120              date  and  time separator characters for DATE and TIME constants
1121              apply also to DATETIME constants.
1122
1123       OPERATORS
1124
1125       Remind has the following operators.  Operators on the  same  line  have
1126       equal  precedence, while operators on lower lines have lower precedence
1127       than those on higher lines.  The operators approximately correspond  to
1128       C operators.
1129
1130            !  -     (unary logical negation and arithmetic negation)
1131            *  /  %
1132            +  -
1133            <  <=  >  >=
1134            ==  !=
1135            &&
1136            ||
1137
1138       DESCRIPTION OF OPERATORS
1139
1140       !      Logical  negation.  Can be applied to an INT type.  If the oper‐
1141              and is non-zero, returns zero.  Otherwise, returns 1.
1142
1143       -      Unary minus.  Can be applied to an INT.  Returns the negative of
1144              the operand.
1145
1146       *      Multiplication.  Returns the product of two INTs.
1147
1148       /      Integer  division.  Returns the quotient of two INTs, discarding
1149              the remainder.
1150
1151       %      Modulus.   Returns  the  remainder  upon  dividing  one  INT  by
1152              another.
1153
1154       +      Has several uses.  These are:
1155
1156              INT + INT - returns the sum of two INTs.
1157
1158              INT + TIME or TIME + INT - returns a TIME obtained by adding INT
1159              minutes to the original TIME.
1160
1161              INT + DATE or DATE + INT - returns a DATE obtained by adding INT
1162              days to the original DATE.
1163
1164              INT  +  DATETIME or DATETIME + INT - returns a DATETIME obtained
1165              by adding INT minutes to the original DATETIME.
1166
1167              STRING + STRING - returns a STRING that is the concatenation  of
1168              the two original STRINGs.
1169
1170              STRING + anything or anything + STRING - converts the non-STRING
1171              argument to a STRING, and then performs concatenation.  See  the
1172              coerce() function.
1173
1174       -      Has several uses.  These are:
1175
1176              INT - INT - returns the difference of two INTs.
1177
1178              DATE - DATE - returns (as an INT) the difference in days between
1179              two DATEs.
1180
1181              TIME - TIME - returns (as an  INT)  the  difference  in  minutes
1182              between two TIMEs.
1183
1184              DATETIME - DATETIME - returns (as an INT) the difference in min‐
1185              utes between two DATETIMEs.
1186
1187              DATE - INT - returns a DATE that is INT days  earlier  than  the
1188              original DATE.
1189
1190              TIME - INT - returns a TIME that is INT minutes earlier than the
1191              original TIME.
1192
1193              DATETIME - INT - returns a DATETIME that is INT minutes  earlier
1194              than the original DATETIME.
1195
1196       <, <=, >, and >=
1197              These  are  the comparison operators.  They can take operands of
1198              any type, but both operands must be of the same type.  The  com‐
1199              parison operators return 1 if the comparison is true, or 0 if it
1200              is false.  Note that string comparison  is  done  following  the
1201              lexical  ordering  of  characters on your system, and that upper
1202              and lower case are distinct for these operators.
1203
1204       ==, != == tests for equality, returning 1 if its  operands  are  equal,
1205              and 0 if they are not.  != tests for inequality.
1206
1207              If  the  operands  are not of the same type, == returns 0 and !=
1208              returns 1.  Again, string comparisons are case-sensitive.
1209
1210       &&     This is the logical AND operator.  Both of its operands must  be
1211              of  type INT.  It returns 1 if both operands are non-zero, and 0
1212              otherwise.
1213
1214       ||     This is the logical OR operator.  Both of its operands  must  be
1215              of  type INT.  It returns 1 if either operand is non-zero, and 0
1216              otherwise.
1217
1218       NOTES
1219
1220       Operators of equal precedence are always evaluated from left to  right,
1221       except where parentheses dictate otherwise.  This is important, because
1222       the enhanced "+" operator is not necessarily associative.  For example:
1223
1224            1 + 2 + "string" + 3 + 4  yields "3string34"
1225            1 + (2 + "string") + (3 + 4)  yields "12string7"
1226            12:59 + 1 + "test"  yields "13:00test"
1227            12:59 + (1 + "test")  yields "12:591test"
1228
1229       The logical operators are not  so-called  short-circuit  operators,  as
1230       they  are  in C.  Both operands are always evaluated.  Thus, an expres‐
1231       sion such as:
1232
1233            (f!=0) && (100/f <= 3)
1234
1235       will cause an error if f is zero.
1236
1237       VARIABLES
1238
1239       Remind allows you to assign values to variables.  The  SET  command  is
1240       used as follows:
1241
1242       SET var expr
1243
1244       Var  is  the name of a variable.  It must start with a letter or under‐
1245       score, and consist only of letters, digits and underscores.   Only  the
1246       first 12 characters of a variable name are significant.  Variable names
1247       are not case sensitive; thus, "Afoo" and "afOo" are the same  variable.
1248       Examples:
1249
1250            SET a 10 + (9*8)
1251            SET b "This is a test"
1252            SET mydir getenv("HOME")
1253            SET time 12:15
1254            SET date today()
1255
1256       Note  that variables themselves have no type.  They take on the type of
1257       whatever you store in them.
1258
1259       To delete a variable, use the UNSET command:
1260
1261       UNSET var [var...]
1262
1263       For example, to delete all the variables declared above, use:
1264
1265            UNSET a b mydir time date
1266
1267       SYSTEM VARIABLES
1268
1269       In addition to the regular user variables, Remind has  several  "system
1270       variables"  that  are  used  to query or control the operating state of
1271       Remind.  System variables are available starting from version  03.00.07
1272       of Remind.
1273
1274       All system variables begin with a dollar sign '$'.  They can be used in
1275       SET commands and expressions just as regular variables can.  All system
1276       variables  always  hold  values of a specified type.  In addition, some
1277       system variables cannot be modified, and you cannot create  new  system
1278       variables.   System  variables  can  be initialized on the command line
1279       with the -i option, but you may need to quote them to avoid having  the
1280       shell  interpret  the dollar sign.  System variable names are not case-
1281       sensitive.
1282
1283       The following system variables are defined.  Those  marked  "read-only"
1284       cannot be changed with the SET command.  All system variables hold val‐
1285       ues of type INT, unless otherwise specified.
1286
1287       $CalcUTC
1288              If 1 (the default), then Remind uses C library functions to cal‐
1289              culate  the  number  of minutes between local and Universal Time
1290              Coordinated.  This affects astronomical calculations  (sunrise()
1291              for  example.)  If 0, then you must supply the number of minutes
1292              between local and Universal Time Coordinated in the $MinsFromUTC
1293              system variable.
1294
1295       $CalMode (read-only)
1296              If  non-zero,  then  the  -c  option was supplied on the command
1297              line.
1298
1299       $Daemon (read-only)
1300              If the daemon mode -z was invoked, contains the number  of  min‐
1301              utes  between  wakeups.  If not running in daemon mode, contains
1302              0.  For the MS-DOS version, always contains 0.
1303
1304       $DateSep
1305              This variable can be set only to "/" or "-".  It holds the char‐
1306              acter  used  to separate portions of a date when Remind prints a
1307              DATE or DATETIME value.
1308
1309       $DefaultPrio
1310              The default priority assigned to reminders  without  a  PRIORITY
1311              clause.   You  can set this as required to adjust the priorities
1312              of blocks of reminders without having  to  type  priorities  for
1313              individual  reminders.  At startup, $DefaultPrio is set to 5000;
1314              it can range from 0 to 9999.
1315
1316       $DontFork (read-only)
1317              If non-zero, then the -c option  was  supplied  on  the  command
1318              line.  For the MS-DOS version, always contains 1.
1319
1320       $DontTrigAts (read-only)
1321              If  non-zero,  then  the  -a  option was supplied on the command
1322              line.  For the MS-DOS version, always contains 0.
1323
1324       $DontQueue (read-only)
1325              If non-zero, then the -q option  was  supplied  on  the  command
1326              line.  For the MS-DOS version, always contains 1.
1327
1328       $EndSent (STRING type)
1329              Contains a list of characters that end a sentence.  The MSF key‐
1330              word inserts two  spaces  after  these  characters.   Initially,
1331              $EndSent is set to ".!?" (period, exclamation mark, and question
1332              mark.)
1333
1334       $EndSentIg (STRING type)
1335              Contains a list of characters that should be  ignored  when  MSF
1336              decides  whether  or  not  to place two spaces after a sentence.
1337              Initially, is set to  "'>)]}"+CHAR(34)  (single-quote,  greater-
1338              than, right parenthesis, right bracket, right brace, and double-
1339              quote.)
1340
1341              For example, the default values work as follows:
1342
1343                   MSF He said, "Huh! (Two spaces will follow this.)"  Yup.
1344
1345              because the final parenthesis and quote  are  ignored  (for  the
1346              purposes of spacing) when they follow a period.
1347
1348       $FirstIndent
1349              The number of spaces by which to indent the first line of a MSF-
1350              type reminder.  The default is 0.
1351
1352       $FoldYear
1353              The standard Unix library functions may have difficulty  dealing
1354              with  dates later than 2037.  If this variable is set to 1, then
1355              the UTC calculations "fold back" years later  than  2037  before
1356              using  the  Unix  library  functions.   For example, to find out
1357              whether or not daylight savings time is in effect in June, 2077,
1358              the year is "folded back" to 2010, because both years begin on a
1359              Monday, and both are non-leapyears.  The rules for daylight sav‐
1360              ings  time are thus presumed to be identical for both years, and
1361              the Unix library functions can handle 2010.   By  default,  this
1362              variable  is  0.  Set it to 1 if the sun or UTC functions misbe‐
1363              have for years greater than 2037.
1364
1365       $FormWidth
1366              The maximum width of each line of text for  formatting  MSF-type
1367              reminders.  The default is 72.  If an MSF-type reminder contains
1368              a word too long to fit in this width, it will not be truncated -
1369              the width limit will be ignored.
1370
1371       $HushMode (read-only)
1372              If  non-zero,  then  the  -h  option was supplied on the command
1373              line.
1374
1375       $IgnoreOnce (read-only)
1376              If non-zero, then the -o option  was  supplied  on  the  command
1377              line,  or  a date different from today's true date was supplied.
1378              If non-zero, then ONCE directives will be ignored.
1379
1380       $InfDelta (read-only)
1381              If non-zero, then the -t option  was  supplied  on  the  command
1382              line.
1383
1384       $LatDeg, $LatMin, $LatSec
1385              These  specify the latitude of your location.  $LatDeg can range
1386              from -90 to 90, and the others from -59 to 59.   Northern  lati‐
1387              tudes  are  positive;  southern ones are negative.  For southern
1388              latitudes, all three components should be negative.
1389
1390       $Location (STRING type)
1391              This is a string specifying the name of your  location.   It  is
1392              usually  the  name of your town or city.  It can be set to what‐
1393              ever you like, but good style indicates that it should  be  kept
1394              consistent with the latitude and longitude system variables.
1395
1396       $LongDeg, $LongMin, $LongSec
1397              These  specify  the  longitude  of  your location.  $LongDeg can
1398              range from -180 to 180.  Western longitudes are positive;  east‐
1399              ern ones are negative.
1400
1401              The latitude and longitude information is required for the func‐
1402              tions sunrise() and sunset().  Default values  can  be  compiled
1403              into  Remind,  or you can SET the correct values at the start of
1404              your reminder scripts.
1405
1406       $MaxSatIter
1407              The  maximum  number  of  iterations  for  the  SATISFY   clause
1408              (described later.)  Must be at least 10.
1409
1410       $MinsFromUTC
1411              The  number  of  minutes  between Universal Time Coordinated and
1412              local time.  If $CalcUTC is non-zero, this  is  calculated  upon
1413              startup  of  Remind.  Otherwise, you must set it explicitly.  If
1414              $CalcUTC is zero, then $MinsFromUTC is used in the  astronomical
1415              calculations.   You  must  adjust  it  for daylight savings time
1416              yourself.  Also, if you want to  initialize  $MinsFromUTC  using
1417              the -i command-line option, you must also set $CalcUTC to 0 with
1418              the -i option.
1419
1420       $NextMode (read-only)
1421              If non-zero, then the -n option  was  supplied  on  the  command
1422              line.
1423
1424       $NumQueued (read-only)
1425              Contains  the  number  of reminders queued so far for background
1426              timed triggering.  For MS-DOS, always returns 0.
1427
1428       $NumTrig (read-only)
1429              Contains the number of reminders triggered for the current date.
1430              One  use  for  this variable is as follows:  Suppose you wish to
1431              shade in the box of a PostScript calendar whenever a holiday  is
1432              triggered.   You  could  save the value of $NumTrig in a regular
1433              variable prior to executing a block of  holiday  reminders.   If
1434              the  value  of  $NumTrig after the holiday block is greater than
1435              the saved value, then at least one holiday  was  triggered,  and
1436              you  can execute the command to shade in the calendar box.  (See
1437              the section "Calendar Mode".)
1438
1439              Note that $NumTrig is affected only by REM commands; triggers in
1440              IFTRIG commands do not affect it.
1441
1442       $PrefixLineNo (read-only)
1443              If  non-zero,  then  the  -l  option was supplied on the command
1444              line.
1445
1446       $PSCal (read-only)
1447              If non-zero, then the -p option  was  supplied  on  the  command
1448              line.
1449
1450       $RunOff (read-only)
1451              If non-zero, the RUN directives are disabled.
1452
1453       $SimpleCal (read-only)
1454              Set  to  a non-zero value if either of the -p or -s command-line
1455              options was supplied.
1456
1457       $SortByDate (read-only)
1458              Set to 0 if no -g option is  used,  1  if  sorting  by  date  in
1459              ascending order, or 2 if sorting by date in descending order.
1460
1461       $SortByPrio (read-only)
1462              Set  to  0  if no -g option is used, 1 if sorting by priority in
1463              ascending order, or 2  if  sorting  by  priority  in  descending
1464              order.
1465
1466       $SortByTime (read-only)
1467              Set  to  0  if  no  -g  option  is used, 1 if sorting by time in
1468              ascending order, or 2 if sorting by time in descending order.
1469
1470       $SubsIndent
1471              The number of spaces by which all lines (except the first) of an
1472              MSF-type reminder should be indented.  The default is 0.
1473
1474       Note:   If  any of the calendar modes are in effect, then the values of
1475       $Daemon, $DontFork, $DontTrigAts, $DontQueue,  $HushMode,  $IgnoreOnce,
1476       $InfDelta, and $NextMode are not meaningful.
1477
1478       $TimeSep
1479              This variable can be set only to ":" or ".".  It holds the char‐
1480              acter used to separate portions of a time when Remind  prints  a
1481              TIME or DATETIME value.
1482
1483       BUILT-IN FUNCTIONS
1484
1485       Remind has a plethora of built-in functions.  The syntax for a function
1486       call is the same as in C - the function name,  followed  a  comma-sepa‐
1487       rated  list  of arguments in parentheses.  Function names are not case-
1488       sensitive.  If a function takes no arguments, it must  be  followed  by
1489       "()"  in  the  function call.  Otherwise, Remind will interpret it as a
1490       variable name, and probably not work correctly.
1491
1492       In the descriptions below, short forms are used  to  denote  acceptable
1493       types  for  the  arguments.   The characters "i", "s", "d", "t" and "q"
1494       denote INT, STRING, DATE, TIME and  DATETIME  arguments,  respectively.
1495       If an argument can be one of several types, the characters are concate‐
1496       nated.  For example, "di_arg" denotes an argument that can be a DATE or
1497       an INT.  "x_arg" denotes an argument that can be of any type.  The type
1498       of the argument is followed by an underscore and an  identifier  naming
1499       the argument.
1500
1501       The built-in functions are:
1502
1503       abs(i_num)
1504              Returns the absolute value of num.
1505
1506       access(s_file, si_mode)
1507              Tests  the  access permissions for the file file.  Mode can be a
1508              string, containing a mix of the characters "rwx" for read, write
1509              and  execute  permission  testing.  Alternatively, mode can be a
1510              number as described in the  UNIX  access(2)  system  call.   The
1511              function  returns  0 if the file can be accessed with the speci‐
1512              fied mode, and -1 otherwise.
1513
1514       args(s_fname)
1515              Returns the number of arguments  expected  by  the  user-defined
1516              function  fname,  or -1 if no such user-defined function exists.
1517              Note that this function examines  only  user-defined  functions,
1518              not built-in functions.  Its main use is to determine whether or
1519              not a particular user-defined function has been  defined  previ‐
1520              ously.   The  args()  function  is available only in versions of
1521              Remind from 03.00.04 and up.
1522
1523       asc(s_string)
1524              Returns an INT that is the ASCII code of the first character  in
1525              string.  As a special case, asc("") returns 0.
1526
1527       baseyr()
1528              Returns  the "base year" that was compiled into Remind (normally
1529              1990.)  All dates are stored internally as the  number  of  days
1530              since 1 January of baseyr().
1531
1532       char(i_i1 [,i_i2...])
1533              This  function can take any number of INT arguments.  It returns
1534              a STRING consisting of the characters  specified  by  the  argu‐
1535              ments.   Note  that none of the arguments can be 0, unless there
1536              is only one argument.  As a special case, char(0) returns "".
1537
1538              Note that because Remind does not support escaping of characters
1539              in strings, the only way to get a double-quote in a string is to
1540              use char(34).
1541
1542       choose(i_index, x_arg1 [,x_arg2...])
1543              Choose must take at least two arguments, the first of  which  is
1544              an  INT.   If  index  is  n, then the nth subsequent argument is
1545              returned.  If index is less than 1, then arg1 is  returned.   If
1546              index  is  greater than the number of subsequent arguments, then
1547              the last argument is returned.  Examples:
1548
1549                 choose(0, "foo", 1:13, 1000) returns "foo"
1550                 choose(1, "foo", 1:13, 1000) returns "foo"
1551                 choose(2, "foo", 1:13, 1000) returns 1:13
1552                 choose(3, "foo", 1:13, 1000) returns 1000
1553                 choose(4, "foo", 1:13, 1000) returns 1000
1554              Note that all arguments to choose() are always evaluated.
1555
1556       coerce(s_type, x_arg)
1557              This function converts arg to the specified type, if  such  con‐
1558              version  is  possible.   Type  must  be  one of "INT", "STRING",
1559              "DATE", "TIME" or "DATETIME" (case-insensitive).  The conversion
1560              rules are as follows:
1561
1562              If  arg  is  already  of  the  type  specified,  it  is returned
1563              unchanged.
1564
1565              If type is "STRING", then arg is converted to a string  consist‐
1566              ing of its printed representation.
1567
1568              If  type is "DATE", then an INT arg is converted by interpreting
1569              it as the number of days since 1 January baseyr().  A STRING arg
1570              is  converted  by  attempting to read it as if it were a printed
1571              date.  A DATETIME is converted to a date by  dropping  the  time
1572              component.  A TIME arg cannot be converted to a date.
1573
1574              If  type is "TIME", then an INT arg is converted by interpreting
1575              it as the number of minutes since midnight.   A  STRING  arg  is
1576              converted by attempting to read it as if it were a printed time.
1577              A DATETIME is converted to a time by dropping  the  date  compo‐
1578              nent.  A DATE arg cannot be converted to a time.
1579
1580              If  type  is  "DATETIME", then an INT arg is converted by inter‐
1581              preting it as the number of minutes since  midnight,  1  January
1582              baseyr().   A STRING is converted by attempting to read it as if
1583              it were a printed datetime.  Other types cannot be converted  to
1584              a datetime.
1585
1586              If  type  is  "INT",  then DATE, TIME and DATETIME arguments are
1587              converted using the reverse of procedures  described  above.   A
1588              STRING arg is converted by parsing it as an integer.
1589
1590       current()
1591              Returns  the  current  date and time as a DATETIME object.  This
1592              may be the actual date and time, or may be  the  date  and  time
1593              supplied on the command line.
1594
1595       date(i_y, i_m, i_d)
1596              The  date()  function returns a DATE object with the year, month
1597              and day components specified by y, m and d.
1598
1599       datetime(args)
1600              The datetime() function can take anywhere from two to five argu‐
1601              ments.   It  always  returns a DATETIME generated from its argu‐
1602              ments.
1603
1604              If you supply two arguments, the first must be a  DATE  and  the
1605              second a TIME.
1606
1607              If  you supply three arguments, the first must be a DATE and the
1608              second and third must be INTs.  The second and  third  arguments
1609              are interpreted as hours and minutes and converted to a TIME.
1610
1611              If  you  supply  four  arguments,  the first three must be INTs,
1612              interpreted as the year, month and  day.   The  fourth  argument
1613              must be a TIME.
1614
1615              Finally, if you supply five arguments, they must all be INTs and
1616              are interpreted as year, month, day, hour and minute.
1617
1618       dawn([dq_date])
1619              Returns the time of "civil dawn" on the specified date.  If date
1620              is  omitted,  defaults to today().  If a datetime object is sup‐
1621              plied, only the date component is used.
1622
1623       day(dq_date)
1624              This function takes a DATE  or  DATETIME  as  an  argument,  and
1625              returns an INT that is the day-of-month component of date.
1626
1627       daysinmon(i_m, i_y)
1628              Returns the number of days in month m (1-12) of the year y.
1629
1630       defined(s_var)
1631              Returns 1 if the variable named by var is defined, or 0 if it is
1632              not.
1633              Note that defined() takes a STRING argument; thus, to  check  if
1634              variable X is defined, use:
1635
1636                        defined("X")
1637
1638              and not:
1639
1640                        defined(X)
1641
1642              The  second  example will attempt to evaluate X, and will return
1643              an error if it is undefined or not of type STRING.
1644
1645       dosubst(s_str [,d_date [,t_time]]) or dosubst(s_str [,q_datetime])
1646              Returns a STRING that is the result of passing str  through  the
1647              substitution  filter described earlier.  The parameters date and
1648              time (or datetime) establish the effective trigger date and time
1649              used  by the substitution filter.  If date and time are omitted,
1650              they default to today() and now().
1651
1652              Note that if str does not end with "%", a newline character will
1653              be added to the end of the result.  Also, calling dosubst() with
1654              a date that is in the past (i.e., if date < today())  will  pro‐
1655              duce undefined results.
1656
1657              Dosubst()  is  only  available starting from version 03.00.04 of
1658              Remind.
1659
1660       dusk([dq_date])
1661              Returns the time of "civil twilight" on the specified date.   If
1662              date is omitted, defaults to today().
1663
1664       easterdate(dqi_arg)
1665              If arg is an INT, then returns the date of Easter Sunday for the
1666              specified year.  If arg is a DATE or DATETIME, then returns  the
1667              date  of the next Easter Sunday on or after arg.  (The time com‐
1668              ponent of a datetime is ignored.)
1669
1670       filedate(s_filename)
1671              Returns the modification date of filename.  If filename does not
1672              exist,  or  its  modification  date is before the year baseyr(),
1673              then 1 January of baseyr() is returned.
1674
1675       filedatetime(s_filename)
1676              Returns the modification date and time of filename.  If filename
1677              does  not  exist,  or  its  modification date is before the year
1678              baseyr(), then midnight, 1 January of baseyr() is returned.
1679
1680       filedir()
1681              Returns the directory that contains the current file being  pro‐
1682              cessed.  It may be a relative or absolute pathname, but is guar‐
1683              anteed to be correct for use in an INCLUDE command as follows:
1684
1685                 INCLUDE [filedir()]/stuff
1686
1687              This includes the file "stuff" in the same directory as the cur‐
1688              rent file being processed.
1689
1690       filename()
1691              Returns  (as  a  STRING) the name of the current file being pro‐
1692              cessed by Remind.  Inside included files, returns  the  name  of
1693              the included file.
1694
1695       getenv(s_envvar)
1696              Similar  to  the getenv(2) system call.  Returns a string repre‐
1697              senting  the  value  of  the  specified  environment   variable.
1698              Returns  ""  if  the  environment variable is not defined.  Note
1699              that the names of environment variables are generally  case-sen‐
1700              sitive; thus, getenv("HOME") is not the same as getenv("home").
1701
1702       hour(tq_time)
1703              Returns the hour component of time.
1704
1705       iif(si_test1, x_arg1, [si_test2, x_arg2,...], x_default)
1706              If  test1  is not zero or the null string, returns arg1.  Other‐
1707              wise, if test2 is not zero or the null string, returns arg2, and
1708              so on.  If all of the test arguments are false, returns default.
1709              Note that all arguments are  always  evaluated.   This  function
1710              accepts  an odd number of arguments - note that prior to version
1711              03.00.05 of Remind, it accepted 3 arguments only.   The  3-argu‐
1712              ment  version  of  iif() is compatible with previous versions of
1713              Remind.
1714
1715       index(s_search, s_target [,i_start)
1716              Returns an INT that is the location  of  target  in  the  string
1717              search.  The first character of a string is numbered 1.  If tar‐
1718              get does not exist in search, then 0 is returned.
1719
1720              The optional parameter start specifies the position in search at
1721              which to start looking for target.
1722
1723       isdst([d_date [,t_time]]) or isdst(q_datetime)
1724              Returns  a positive number if daylight savings time is in effect
1725              on the specified date and time.  Date defaults  to  today()  and
1726              time defaults to midnight.
1727
1728              Note  that  this  function is only as reliable as the C run-time
1729              library  functions.   It  is  available  starting  with  version
1730              03.00.07 of Remind.
1731
1732       isleap(idq_arg)
1733              Returns 1 if arg is a leap year, and 0 otherwise.  Arg can be an
1734              INT, DATE or DATETIME object.  If a DATE  or  DATETIME  is  sup‐
1735              plied, then the year component is used in the test.
1736
1737       isomitted(dq_date)
1738              Returns 1 if date is omitted, given the current global OMIT con‐
1739              text.  Returns 0 otherwise.  (If a datetime  is  supplied,  only
1740              the date part is used.)
1741
1742       hebdate(i_day, s_hebmon [,idq_yrstart [,i_jahr [,i_aflag]]])
1743              Support for Hebrew dates - see the section "The Hebrew Calendar"
1744
1745       hebday(dq_date)
1746              Support for Hebrew dates - see the section "The Hebrew Calendar"
1747
1748       hebmon(dq_date)
1749              Support for Hebrew dates - see the section "The Hebrew Calendar"
1750
1751       hebyear(dq_date)
1752              Support for Hebrew dates - see the section "The Hebrew Calendar"
1753
1754       language()
1755              Returns  a STRING naming the language supported by Remind.  (See
1756              "Foreign Language Support.") By default, Remind is  compiled  to
1757              support  English  messages,  so this function returns "English".
1758              For other languages, this function will return the English  name
1759              of  the  language  (e.g.  "German")  Note that language() is not
1760              available in versions of Remind prior to 03.00.02.
1761
1762       lower(s_string)
1763              Returns a STRING with all upper-case characters in  string  con‐
1764              verted to lower-case.
1765
1766       max(x_arg1 [,x_arg2...)
1767              Can  take any number of arguments, and returns the maximum.  The
1768              arguments can be of any type, but must all be of the same  type.
1769              They are compared as with the > operator.
1770
1771       min(x_arg1 [,x_arg2...)
1772              Can  take any number of arguments, and returns the minimum.  The
1773              arguments can be of any type, but must all be of the same  type.
1774              They are compared as with the < operator.
1775
1776       minsfromutc([d_date [,t_time]]) or minsfromutc(q_datetime)
1777              Returns  the  number  of minutes from Universal Time Coordinated
1778              (formerly GMT) to local time on the  specified  date  and  time.
1779              Date  defaults  to  today()  and  time defaults to midnight.  If
1780              local time is before UTC, the result  is  negative.   Otherwise,
1781              the result is positive.
1782
1783              Note  that  this  function is only as reliable as the C run-time
1784              library  functions.   It  is  available  starting  with  version
1785              03.00.07 of Remind.
1786
1787       minute(tq_time)
1788              Returns the minute component of time.
1789
1790       mon(dqi_arg)
1791              If  arg is of DATE or DATETIME type, returns a string that names
1792              the month component of the date.  If arg is an INT from 1 to 12,
1793              returns a string that names the month.
1794
1795       monnum(dq_date)
1796              Returns an INT from 1 to 12, representing the month component of
1797              date.
1798
1799       moondate(i_phase [,d_date [,t_time]]) or moondate(i_phase, q_datetime)
1800              This function returns the date of the first  occurrence  of  the
1801              phase  phase  of  the moon on or after date and time.  Phase can
1802              range from 0 to 3, with 0 signifying new moon, 1 first  quarter,
1803              2  full  moon,  and  3  third  quarter.   If date is omitted, it
1804              defaults to today().  If time is omitted, it  defaults  to  mid‐
1805              night.
1806
1807              For  example,  the  following  returns the date of the next full
1808              moon:
1809
1810                        SET fullmoon moondate(2)
1811
1812       moontime(i_phase [,d_date [,t_time]]) or moontime(i_phase, q_datetime)
1813              This function returns the time of the first  occurrence  of  the
1814              phase  phase  of  the moon on or after date and time.  Phase can
1815              range from 0 to 3, with 0 signifying new moon, 1 first  quarter,
1816              2  full  moon,  and  3  third  quarter.   If date is omitted, it
1817              defaults to today().  If time is omitted, it  defaults  to  mid‐
1818              night.   Moontime()  is  intended to be used in conjunction with
1819              moondate().  The moondate() and moontime() functions  are  accu‐
1820              rate to within a couple of minutes of the times in "Old Farmer's
1821              Almanac" for Ottawa, Ontario.
1822
1823              For example, the following returns the date and time of the next
1824              full moon:
1825
1826                        MSG Next full moon at [moontime(2)] on [moondate(2)]
1827
1828       moondatetime(i_phase   [,d_date  [,t_time]])  or  moondatetime(i_phase,
1829       q_datetime)
1830              This function is similar to moondate and moontime, but returns a
1831              DATETIME result.
1832
1833       moonphase([d_date [,t_time]]) or moonphase(q_datetime)
1834              This  function  returns  the phase of the moon on date and time,
1835              which  default  to  today()  and  midnight,  respectively.   The
1836              returned  value  is  an  integer from 0 to 359, representing the
1837              phase of the moon in degrees.  0 is a new moon, 180  is  a  full
1838              moon, 90 is first-quarter, etc.
1839
1840       nonomitted(dq_start, dq_end [,s_wkday...])
1841              This  function  returns  the  number of non-omitted days between
1842              start and end.  If start is non-omitted,  then  it  is  counted.
1843              end is never counted.
1844
1845              Note that end must be greater than or equal to start or an error
1846              is reported.  In addition to using the global OMIT context,  you
1847              can supply additional arguments that are names of weekdays to be
1848              omitted.
1849
1850              For example, the following line sets a to 11 (assuming no global
1851              OMITs):
1852
1853                   set a nonomitted('2007-08-01', '2007-08-16', "Sat", "Sun")
1854
1855              because  Thursday,  16  August 2007 is the 11th working day (not
1856              counting Saturday and Sunday) after Wednesday, 1 August 2007.
1857
1858              nonomitted has various uses.  For example, many schools run on a
1859              six-day cycle and the day number is not incremented on holidays.
1860              Suppose the school year starts with Day 1 on 4  September  2007.
1861              The following reminder will label day numbers in a calendar:
1862
1863                 IF today() >= '2007-09-04'
1864                     set daynum nonomitted('2007-09-04', today(), "Sat", "Sun")
1865                     REM OMIT SAT SUN SKIP CAL Day [(daynum % 6) + 1]
1866                 ENDIF
1867
1868              Here's a more complex example:  Suppose your normal garbage-col‐
1869              lection day is Thursday, but if any of Monday  through  Thursday
1870              of  a  week  is  a  holiday, the collection day moves to Friday.
1871              Here's one way to solve it:
1872
1873                 FSET prev_monday(x) x - wkdaynum(x-1)
1874
1875                 REM Thu Fri SATISFY [wkdaynum(trigdate()) == 4 && \
1876                          nonomitted(prev_monday(today()), today()+1) == 4 || \
1877                          wkdaynum(trigdate()) == 5 && \
1878                          nonomitted(prev_monday(today()), today()+1) <= 4] \
1879                          MSG Garbage Day
1880
1881              Whew!  (You'll need to see "THE SATISFY CLAUSE" later on.)  We'd
1882              better explain that one: The prev_monday helper function takes a
1883              date and returns the date of the previous Monday.  The REM  com‐
1884              mand will trigger on the first Thursday or Friday that satisfies
1885              one of the following conditions:
1886
1887              1) Either it's a Thursday and there are exactly four non-omitted
1888              days between the previous Monday and tomorrow, or
1889
1890              2)  It's  a  Friday and there are four or fewer non-omitted days
1891              between the previous Monday  and  tomorrow.   We  need  the  "or
1892              fewer"  condition to handle the case of more than one holiday in
1893              a given week.  If that happens, garbage day still only moves  by
1894              one day.
1895
1896              Obviously,  the  answer  you  get from nonomitted depends on the
1897              global OMIT context.  If you use moveable  OMITs,  you  may  get
1898              inconsistent results.
1899
1900       now()  Returns  the  current  system time, as a TIME type.  This may be
1901              the actual time, or a time supplied on the command line.
1902
1903       ord(i_num)
1904              Returns a string that is the ordinal number num.   For  example,
1905              ord(2) returns "2nd", and ord(213) returns "213th".
1906
1907       ostype()
1908              Returns "UNIX".  Remind used to run on OS/2 and MS-DOS, but does
1909              not any longer.
1910
1911       plural(i_num [,s_str1 [,s_str2]])
1912              Can take from one to three arguments.  If one argument  is  sup‐
1913              plied, returns "s" if num is not 1, and "" if num is 1.
1914
1915              If  two arguments are supplied, returns str1 + "s" if num is not
1916              1.  Otherwise, returns str1.
1917
1918              If three arguments are supplied, returns str1 if num is  1,  and
1919              str2 otherwise.
1920
1921       psmoon(i_phase [,i_size [,s_note [,i_notesize]]])
1922              [DEPRECATED]  Returns  a STRING consisting of PostScript code to
1923              draw a moon in the upper-left hand corner of the  calendar  box.
1924              Phase  specifies  the  phase of the moon, and is 0 (new moon), 1
1925              (first quarter), 2 (full moon) or 3 (third quarter).  If size is
1926              specified,  it  controls  the  radius  of the moon in PostScript
1927              units (1/72 inch.)  If it is not specified or is  negative,  the
1928              size of the day-number font is used.
1929
1930              For  example, the following four lines place moon symbols on the
1931              PostScript calendar:
1932
1933                        REM [trigger(moondate(0))] PS [psmoon(0)]
1934                        REM [trigger(moondate(1))] PS [psmoon(1)]
1935                        REM [trigger(moondate(2))] PS [psmoon(2)]
1936                        REM [trigger(moondate(3))] PS [psmoon(3)]
1937
1938              If note is specified, the text is used to annotate the moon dis‐
1939              play.   The font is the same font used for calendar entries.  If
1940              notesize is given, it specifies the font size  to  use  for  the
1941              annotation, in PostScript units (1/72 inch.)  If notesize is not
1942              given, it defaults to the size used for calendar  entries.   (If
1943              you  annotate  the  display, be careful not to overwrite the day
1944              number -- Remind does not check for this.)  For example, if  you
1945              want  the time of each new moon displayed, you could use this in
1946              your reminder script:
1947
1948                   REM [trigger(moondate(0))] PS [psmoon(0, -1, moontime(0)+"")]
1949
1950              Note how the time is coerced to a string  by  concatenating  the
1951              null string.
1952
1953       psshade(i_gray) or psshade(i_red, i_green, i_blue)
1954              [DEPRECATED]  Returns  a STRING that consists of PostScript com‐
1955              mands to shade a calendar box.  Num can range from 0 (completely
1956              black) to 100 (completely white.)  If three arguments are given,
1957              they specify red, green  and  blue  intensity  from  0  to  100.
1958              Here's an example of how to use this:
1959
1960                        REM Sat Sun PS [psshade(95)]
1961
1962              The  above  command  emits  PostScript code to lightly shade the
1963              boxes for Saturday and Sunday in a PostScript calendar.
1964
1965              Note that psmoon and psshade are deprecated; instead you  should
1966              use the SPECIAL SHADE and SPECIAL MOON reminders as described in
1967              "Out-of-Band Reminders."
1968
1969       realcurrent()
1970              Returns (as a DATETIME) the true date and time of  day  as  pro‐
1971              vided  by  the  operating  system.   This is in contrast to cur‐
1972              rent(), which may return a time supplied on the command line.
1973
1974       realnow()
1975              Returns the true time of day as provided by the  operating  sys‐
1976              tem.  This is in contrast to now(), which may return a time sup‐
1977              plied on the command line.
1978
1979       realtoday()
1980              Returns the date as provided by the operating system.   This  is
1981              in contrast to Remind's concept of "today", which may be changed
1982              if it is running in calendar mode, or if a date  has  been  sup‐
1983              plied on the command line.
1984
1985       sgn(i_num)
1986              Returns  -1  if  num is negative, 1 if num is positive, and 0 if
1987              num is zero.
1988
1989       shell(s_cmd [,i_maxlen])
1990              Executes cmd as a system command,  and  returns  the  first  511
1991              characters of output resulting from cmd.  Any whitespace charac‐
1992              ter in the output is converted to a space.  Note that if RUN OFF
1993              has  been executed, or the -r command-line option has been used,
1994              shell() will result in an error, and cmd will not be executed.
1995
1996       If maxlen is specified, then shell() returns the first  maxlen  charac‐
1997       ters  of output (rather than the first 511).  If maxlen is specified as
1998       a negative number, then all the output from cmd is returned.
1999
2000       strlen(s_str)
2001              Returns the length of str.
2002
2003       substr(s_str, i_start [,i_end])
2004              Returns a STRING consisting of all characters in str from  start
2005              up  to  and  including end.  Characters are numbered from 1.  If
2006              end is not supplied, then it defaults to the length of str.
2007
2008       sunrise([dq_date])
2009              Returns a TIME indicating the time of sunrise on  the  specified
2010              date (default today().)  In high latitudes, there may be no sun‐
2011              rise on a particular day, in which case  sunrise()  returns  the
2012              INT 0 if the sun never sets, or 1440 if it never rises.
2013
2014       sunset([dq_date])
2015              Returns  a  TIME  indicating the time of sunset on the specified
2016              date (default today().)  In high latitudes, there may be no sun‐
2017              set  on a particular day, in which case sunset() returns the INT
2018              0 if the sun never rises, or 1440 if it never sets.
2019
2020              The functions sunrise() and sunset() are based on  an  algorithm
2021              in  "Almanac  for Computers for the year 1978" by L. E. Doggett,
2022              Nautical Almanac Office, USNO.  They require  the  latitude  and
2023              longitude  to  be  specified  by  setting the appropriate system
2024              variables.  (See "System Variables".)  The sun functions  should
2025              be  accurate  to within about 2 minutes for latitudes lower than
2026              60 degrees.  The functions are available starting  from  version
2027              03.00.07 of Remind.
2028
2029       time(i_hr, i_min)
2030              Creates  a TIME with the hour and minute components specified by
2031              hr and min.
2032
2033       today()
2034              Returns Remind's notion of "today."  This may be the actual sys‐
2035              tem date, or a date supplied on the command line, or the date of
2036              the calendar entry currently being computed.
2037
2038       trigdate()
2039              Returns the calculated trigger date of the last  REM  or  IFTRIG
2040              command.   If  used  in  the body of a REM command, returns that
2041              command's trigger date.  If the most recent REM command did  not
2042              yield a computable trigger date, returns the integer 0.
2043
2044       trigdatetime()
2045              Similar to trigdate(), but returns a DATETIME if the most recent
2046              triggerable REM command had an AT clause.  If there  was  no  AT
2047              clause,  returns  a  DATE.   If  no  trigger  could be computed,
2048              returns the integer 0.
2049
2050       trigger(d_date   [,t_time    [,i_utcflag]])    or    trigger(q_datetime
2051       [,i_utcflag])
2052              Returns a string suitable for use in a REM command, allowing you
2053              to  calculate  trigger  dates  in  advance.   (See  the  section
2054              "Expression pasting" for more information.)  Note that trigger()
2055              always returns its result in English, even for  foreign-language
2056              versions  of  Remind.   This is to avoid problems with certain C
2057              libraries that do not handle accented characters properly.  Nor‐
2058              mally,  the  date and time are the local date and time; however,
2059              if utcflag is non-zero, the date and time are interpreted as UTC
2060              times, and are converted to local time.  Examples:
2061
2062                   trigger('1993/04/01')
2063
2064              returns "1 April 1993",
2065
2066                   trigger('1994/08/09', 12:33)
2067
2068              returns "9 August 1994 AT 12:33", as does:
2069
2070                   trigger('1994/08/09@12:33').
2071
2072              Finally:
2073
2074                   trigger('1994/12/01', 03:00, 1)
2075
2076              returns  "30  November  1994 AT 22:00" for EST, which is 5 hours
2077              behind UTC.  The value for your time zone may differ.
2078
2079       trigtime()
2080              Returns the time of the last REM command with an AT clause.   If
2081              the last REM did not have an AT clause, returns the integer 0.
2082
2083       trigvalid()
2084              Returns  1  if the value returned by trigdate() is valid for the
2085              most recent REM command, or 0 otherwise.  Sometimes REM commands
2086              cannot calculate a trigger date.  For example, the following REM
2087              command can never be triggered:
2088
2089                 REM Mon OMIT Mon SKIP MSG Impossible!
2090
2091       typeof(x_arg)
2092              Returns "STRING", "INT", "DATE", "TIME" or "DATETIME", depending
2093              on the type of arg.
2094
2095       tzconvert(q_datetime, s_srczone [,s_dstzone])
2096              Converts  datetime  from  the  time zone named by srczone to the
2097              time zone named by dstzone.  If dstzone is omitted, the  default
2098              system time zone is used.  The return value is a DATETIME.  Time
2099              zone names are system-dependent; consult your  operating  system
2100              for legal values.  Here is an example:
2101
2102           tzconvert('2007-07-08@01:14', "Canada/Eastern", "Canada/Pacific")
2103
2104                 returns
2105
2106           2007-07-07@22:14
2107
2108       upper(s_string)
2109              Returns  a  STRING with all lower-case characters in string con‐
2110              verted to upper-case.
2111
2112       value(s_varname [,x_default])
2113              Returns the value  of  the  specified  variable.   For  example,
2114              value("X"+"Y")  returns  the  value  of  variable  XY,  if it is
2115              defined.  If XY is not defined, an error results.
2116
2117              However, if you supply a second argument, it is returned if  the
2118              varname  is  not  defined.   The  expression value("XY", 0) will
2119              return 0 if XY is not defined, and the value  of  XY  if  it  is
2120              defined.
2121
2122       version()
2123              Returns  a string specifying the version of Remind.  For version
2124              03.00.04, returns "03.00.04".  It is guaranteed that as new ver‐
2125              sions  of  Remind  are released, the value returned by version()
2126              will strictly increase, according to the rules for string order‐
2127              ing.
2128
2129       wkday(dqi_arg)
2130              If  arg is a DATE or DATETIME, returns a string representing the
2131              day of the week of the date.  If arg is an  INT  from  0  to  6,
2132              returns the corresponding weekday ("Sunday" to "Saturday").
2133
2134       wkdaynum(dq_date)
2135              Returns a number from 0 to 6 representing the day-of-week of the
2136              specified date.  (0 represents Sunday, and 6  represents  Satur‐
2137              day.)
2138
2139       year(dq_date)
2140              Returns a INT that is the year component of date.
2141

EXPRESSION PASTING

2143       An  extremely  powerful  feature  of Remind is its macro capability, or
2144       "expression pasting."
2145
2146       In almost any situation where Remind is not  expecting  an  expression,
2147       you  can "paste" an expression in.  To do this, surround the expression
2148       with square brackets.  For example:
2149
2150            REM [trigger(mydate)] MSG foo
2151
2152       This evaluates the expression "trigger(mydate)", where "mydate" is pre‐
2153       sumably  some  pre-computed variable, and then "pastes" the result into
2154       the command-line for the parser to process.
2155
2156       A formal description of this is:  When Remind encounters a  "pasted-in"
2157       expression,  it  evaluates  the expression, and coerces the result to a
2158       STRING.  It then substitutes the string for the  pasted-in  expression,
2159       and  continues  parsing.  Note, however, that expressions are evaluated
2160       only once, not recursively.  Thus, writing:
2161
2162            ["[a+b]"]
2163
2164       causes Remind to read the token "[a+b]".  It does not interpret this as
2165       a  pasted-in  expression.  In fact, the only way to get a literal left-
2166       bracket into a reminder is to use ["["].
2167
2168       You can use expression pasting almost anywhere.  However, there  are  a
2169       few exceptions:
2170
2171       o      If  Remind is expecting an expression, as in the SET command, or
2172              the IF command, then no expression  pasting  takes  place.   The
2173              expression  is  simply  evaluated as if the square brackets were
2174              not there.
2175
2176       o      You cannot use expression pasting for the first token on a line.
2177              For example, the following will not work:
2178
2179                 ["SET"] a 1
2180
2181              This restriction is because Remind must be able to unambiguously
2182              determine the first token of a line for  the  flow-control  com‐
2183              mands (to be discussed later.)
2184
2185              In  fact,  if Remind cannot determine the first token on a line,
2186              it assumes that it is a REM command.  If  expression-pasting  is
2187              used,  Remind  assumes it is a REM command.  Thus, the following
2188              three commands are equivalent:
2189
2190                        REM 12 Nov 1993 AT 13:05 MSG BOO!
2191                        12 Nov 1993 AT 13:05 MSG BOO!
2192                        [12] ["Nov " + 1993] AT [12:05+60] MSG BOO!
2193
2194       o      You cannot use expression-pasting to determine  the  type  (MSG,
2195              CAL,  etc.)  of a REM command.  You can paste expressions before
2196              and after the MSG, etc keywords, but cannot  do  something  like
2197              this:
2198
2199                 REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]
2200
2201       COMMON PITFALLS IN EXPRESSION PASTING
2202
2203       Remember,  when  pasting  in  expressions,  that  extra  spaces are not
2204       inserted.  Thus, something like:
2205
2206            REM[expr]MSG[expr]
2207
2208       will probably fail.
2209
2210       If you use an expression to calculate a delta or back, ensure that  the
2211       result is a positive number.  Something like:
2212
2213            REM +[mydelta] Nov 12 1993 MSG foo
2214
2215       will fail if mydelta happens to be negative.
2216

FLOW CONTROL COMMANDS

2218       Remind  has  commands that control the flow of a reminder script.  Nor‐
2219       mally, reminder scripts are processed sequentially.   However,  IF  and
2220       related  commands  allow  you  to process files conditionally, and skip
2221       sections that you don't want interpreted.
2222
2223       THE IF COMMAND
2224
2225       The IF command has the following form:
2226
2227            IF expr
2228                 t-command
2229                 t-command...
2230            ELSE
2231                 f-command
2232                 f-command...
2233            ENDIF
2234
2235       Note that the commands are shown indented for clarity.  Also, the  ELSE
2236       portion can be omitted.  IF commands can be nested up to a small limit,
2237       probably around 8 or 16 levels of nesting, depending on your system.
2238
2239       If the expr evaluates to a non-zero INT, or a non-null STRING, then the
2240       IF  portion  is  considered  true, and the t-commands are executed.  If
2241       expr evaluates to zero or null, then the f-commands (if the  ELSE  por‐
2242       tion  is  present) are executed.  If expr is not of type INT or STRING,
2243       then it is an error.
2244
2245       Examples:
2246
2247            IF defined("want_hols")
2248                 INCLUDE /usr/share/remind/holidays
2249            ENDIF
2250
2251            IF today() > '1992/2/10'
2252                 set missed_ap "You missed it!"
2253            ELSE
2254                 set missed_ap "Still have time..."
2255            ENDIF
2256
2257       THE IFTRIG COMMAND
2258
2259       The IFTRIG command is similar to an IF command, except that it computes
2260       a  trigger  (as  in the REM command), and evaluates to true if a corre‐
2261       sponding REM command would trigger.  Examples:
2262
2263            IFTRIG 1 Nov
2264                 ; Executed on 1 Nov
2265            ELSE
2266                 ; Executed except on 1 Nov
2267            ENDIF
2268
2269            IFTRIG 1 -1 OMIT Sat Sun +4
2270                 ; Executed on last working day of month,
2271                 ; and the 4 working days preceding it
2272            ELSE
2273                 ; Executed except on above days
2274            ENDIF
2275
2276       Note that the IFTRIG command computes a  trigger  date,  which  can  be
2277       retrieved  with the trigdate() function.  You can use all of the normal
2278       trigger components, such as UNTIL, delta, etc in the IFTRIG command.
2279

USER-DEFINED FUNCTIONS

2281       In addition to the built-in functions, Remind allows you to define your
2282       own functions.  The FSET command does this for you:
2283
2284       FSET fname(args) expr
2285
2286       Fname  is the name of the function, and follows the convention for nam‐
2287       ing variables.  Args is a comma-separated list of arguments,  and  expr
2288       is  an expression.  Args can be empty, in which case you define a func‐
2289       tion taking no parameters.  Here are some examples:
2290
2291            FSET double(x) 2*x
2292            FSET yeardiff(date1, date2) year(date1) - year(date2)
2293            FSET since(x) ord(year(trigdate())-x)
2294
2295       The last function is useful in birthday reminders.  For example:
2296
2297            REM 1 Nov +12 MSG Dean's [since(1984)] birthday is %b.
2298
2299       Dean was born in 1984.  The above example, on 1  November  1992,  would
2300       print:
2301
2302            Dean's 8th birthday is today.
2303
2304       Notes:
2305
2306       o      If  you  access  a  variable  in expr that is not in the list of
2307              arguments, the "global" value (if any) is used.
2308
2309       o      Function and parameter names are significant only to 12  charac‐
2310              ters.
2311
2312       o      The  value()  function  always  accesses the "global" value of a
2313              variable, even if it has the same  name  as  an  argument.   For
2314              example:
2315
2316                        fset func(x) value("x")
2317                        set x 1
2318                        set y func(5)
2319
2320              The above sequence sets y to 1, which is the global value of x.
2321
2322       o      User-defined functions may call other functions, including other
2323              user-defined  functions.   However,  recursive  calls  are   not
2324              allowed.
2325
2326       o      User-defined  functions  are  not  syntax-checked  when they are
2327              defined; parsing occurs only when they are called.
2328
2329       o      If a user-defined function has the same name as a built-in func‐
2330              tion,  it is ignored and the built-in function is used.  To pre‐
2331              vent conflicts with future versions of Remind (which may  define
2332              more  built-in functions), you may wish to name all user-defined
2333              functions beginning with an underscore.
2334

PRECISE SCHEDULING

2336       The WARN keyword allows precise control over advance warning in a  more
2337       flexible manner than the delta mechanism.  It should be followed by the
2338       name of a user-defined function, warn_function.
2339
2340       If a warn_function is supplied, then it must take one argument of  type
2341       INT.  Remind ignores any delta, and instead calls warn_function succes‐
2342       sively with the arguments 1, 2, 3, ...
2343
2344       Warn_function's return value n is interpreted as follows:
2345
2346       o      If n is positive, then the reminder is triggered exactly n  days
2347              before its trigger date.
2348
2349       o      If n is negative, then it is triggered n days before its trigger
2350              date, not counting OMITted days.
2351
2352       As an example, suppose you wish to be warned of  American  Independence
2353       Day 5, 3, and 1 days in advance.  You could use this:
2354
2355            FSET _wfun(x) choose(x, 5, 3, 1, 0)
2356            REM 4 July WARN _wfun MSG American Independence Day is %b.
2357
2358       NOTES
2359
2360       1      If  an error occurs during the evaluation of warn_function, then
2361              Remind stops calling it and simply issues the  reminder  on  its
2362              trigger date.
2363
2364       2      If the absolute-values of the return values of warn_function are
2365              not monotonically decreasing, Remind stops calling it and issues
2366              the reminder on its trigger date.
2367
2368       3      Warn_function should (as a matter of good style) return 0 as the
2369              final value in  its  sequence  of  return  values.   However,  a
2370              reminder  will  always be triggered on its trigger date, regard‐
2371              less of what warn_function does.
2372
2373       Similarly to WARN, the SCHED keyword allows precise  control  over  the
2374       scheduling  of timed reminders.  It should be followed by the name of a
2375       user-defined function, sched_function.
2376
2377       If a scheduling function is supplied, then it must take one argument of
2378       type  INT.  Rather than using the AT time, time delta, and time repeat,
2379       Remind calls the scheduling function to determine when to  trigger  the
2380       reminder.   The first time the reminder is queued, the scheduling func‐
2381       tion is called with an argument of 1.  Each time the reminder is  trig‐
2382       gered, it is re-scheduled by calling the scheduling function again.  On
2383       each call, the argument is incremented by one.
2384
2385       The return value of the scheduling function must be an INT or  a  TIME.
2386       If  the return value is a TIME, then the reminder is re-queued to trig‐
2387       ger at that time.  If it is a positive integer n, then the reminder  is
2388       re-queued  to  trigger  at  the  previous  trigger time plus n minutes.
2389       Finally, if it is a negative integer or zero, then the reminder is  re-
2390       queued  to  trigger n minutes before the AT time.  Note that there must
2391       be an AT clause for the SCHED clause to do anything.
2392
2393       Here's an example:
2394
2395            FSET _sfun(x) choose(x, -60, 30, 15, 10, 3, 1, 1, 1, 1, 0)
2396            REM AT 13:00 SCHED _sfun MSG foo
2397
2398       The reminder would first be triggered at 13:00-60 minutes, or at 12:00.
2399       It  would next be triggered 30 minutes later, at 12:30.  Then, it would
2400       be triggered at 12:45, 12:55, 12:58, 12:59, 13:00, 13:01 and 13:02.
2401
2402       NOTES
2403
2404       1      If an error occurs during the  evaluation  of  sched_func,  then
2405              Remind  reverts  to  using  the AT time and the delta and repeat
2406              values, and never calls sched_func again.
2407
2408       2      If processing sched_func yields a time earlier than the  current
2409              system  time,  it  is repeatedly called with increasing argument
2410              until it yields a value greater than or  equal  to  the  current
2411              time.   However, if the sequence of values calculated during the
2412              repetition is not strictly increasing, then  Remind  reverts  to
2413              the default behaviour and never calls sched_func again.
2414
2415       3      It  is  quite  possible  using  sched_func  to keep triggering a
2416              reminder even after the AT-time.  However, it is not possible to
2417              reschedule a reminder past midnight - no crossing of date bound‐
2418              aries is allowed.  Also, it is quite possible to not  trigger  a
2419              reminder  on  the  AT  time  when you use a scheduling function.
2420              However, if your scheduling function is terminated (for  reasons
2421              1  and  2)  before the AT time of the reminder, it will be trig‐
2422              gered at the AT time, because normal processing takes over.
2423
2424       4      Your scheduling functions should (as a  matter  of  good  style)
2425              return 0 when no more scheduling is required.  See the example.
2426
2427       5      All  scheduling  functions are evaluated after the entire Remind
2428              script has been read in.  So whatever function  definitions  are
2429              in effect at the end of the script are used.
2430

THE SATISFY CLAUSE

2432       The form of REM that uses SATISFY is as follows:
2433
2434       REM trigger SATISFY expr
2435
2436       The  way  this  works is as follows:  Remind first calculates a trigger
2437       date, in the normal fashion.  Next, it sets trigdate()  to  the  calcu‐
2438       lated  trigger date.  It then evaluates expr.  If the result is not the
2439       null string or zero, processing ends.  Otherwise, Remind  computes  the
2440       next  trigger  date, and re-tests expr.  This iteration continues until
2441       expr evaluates to non-zero or non-null, or until  the  iteration  limit
2442       specified with the -x command-line option is reached.
2443
2444       If  expr  is  not  satisfied, then trigvalid() is set to 0.  Otherwise,
2445       trigvalid() is set to 1.  In any event, no error message is issued.
2446
2447       This is really useful only if expr involves a call  to  the  trigdate()
2448       function; otherwise, expr will not change as Remind iterates.
2449
2450       An example of the usefulness of SATISFY:  Suppose you wish to be warned
2451       of every Friday the 13th.  Your first attempt may be:
2452
2453            # WRONG!
2454            REM Fri 13 +2 MSG Friday the 13th is %b.
2455
2456       But this won't work.  This reminder triggers on the first Friday on  or
2457       after  the 13th of each month.  The way to do it is with a more compli‐
2458       cated sequence:
2459
2460            REM 13 SATISFY wkdaynum(trigdate()) == 5
2461            IF trigvalid()
2462                 REM [trigger(trigdate())] +2 MSG \
2463                 Friday the 13th is %b.
2464            ENDIF
2465
2466       Let's see how this works.  The SATISFY clause iterates through all  the
2467       13ths of successive months, until a trigger date is found whose day-of-
2468       week is Friday (== 5).  If a valid date was found, we  use  the  calcu‐
2469       lated  trigger date (converted into a trigger format with the trigger()
2470       function) to set up the next reminder.
2471
2472       We could also have written:
2473
2474            REM Fri SATISFY day(trigdate()) == 13
2475
2476       but this would result in more iterations, since  "Fridays"  occur  more
2477       often than "13ths of the month."
2478
2479       This  technique of using one REM command to calculate a trigger date to
2480       be used by another command is quite powerful.  For example, suppose you
2481       wanted to OMIT Labour day, which is the first Monday in September.  You
2482       could use:
2483
2484            # Note: SATISFY 1 is an idiom for "do nothing"
2485            REM Mon 1 Sept SATISFY 1
2486            OMIT [trigger(trigdate())]
2487
2488       CAVEAT: This only omits the next Labour Day, not all Labour Days in the
2489       future.   This  could  cause  strange  results, as the OMIT context can
2490       change depending on the current date.  For example, if you use the fol‐
2491       lowing command after the above commands:
2492
2493            REM Mon AFTER msg hello
2494
2495       the  result  will  not be as you expect.  Consider producing a calendar
2496       for September, 1992.  Labour Day was  on  Monday,  7  September,  1992.
2497       However,  when  Remind gets around to calculating the trigger for Tues‐
2498       day, 8 September, 1992, the OMIT command will now  be  omitting  Labour
2499       Day  for 1993, and the "Mon AFTER" command will not be triggered.  (But
2500       see the description of SCANFROM in the section "Details  about  Trigger
2501       Computation.")
2502
2503       It  is  probably  best  to  stay away from computing OMIT trigger dates
2504       unless you keep these pitfalls in mind.
2505
2506       For versions of Remind starting from 03.00.07, you can include  a  MSG,
2507       RUN, etc. clause in a SATISFY clause as follows:
2508
2509            REM trigger_stuff SATISFY [expr] MSG body
2510
2511       Note  that  for this case only, the expr after SATISFY must be enclosed
2512       in braces.  It must come after all the other components of the trigger,
2513       and  immediately  before the MSG, RUN, etc. keyword.  If expr cannot be
2514       satisfied, then the reminder is not triggered.
2515
2516       Thus, the "Friday the 13th" example can be expressed more compactly as:
2517
2518            REM 13 +2 SATISFY [wkdaynum(trigdate()) == 5] \
2519                 MSG Friday the 13th is %b.
2520
2521       And you can trigger a reminder on  Mondays,  Wednesdays  and  Thursdays
2522       occurring on odd-numbered days of the month with the following:
2523
2524            REM Mon Wed Thu SATISFY [day(trigdate())%2] \
2525                 MSG Here it is!!!
2526

DEBUGGING REMINDER SCRIPTS

2528       Although  the  command-line  -d  option  is useful for debugging, it is
2529       often overkill.  For example, if you turn  on  the  -dx  option  for  a
2530       reminder  file  with many complex expressions, you'll get a huge amount
2531       of output.  The DEBUG command allows you to control the debugging flags
2532       under program control.  The format is:
2533
2534       DEBUG [+flagson] [-flagsoff]
2535
2536       Flagson  and flagsoff consist of strings of the characters "extvl" that
2537       correspond to the  debugging  options  discussed  in  the  command-line
2538       options  section.   If  preceded with a "+", the corresponding group of
2539       debugging options is switched on.  Otherwise, they  are  switched  off.
2540       For example, you could use this sequence to debug a complicated expres‐
2541       sion:
2542
2543            DEBUG +x
2544            set a very_complex_expression(many_args)
2545            DEBUG -x
2546
2547       THE DUMPVARS COMMAND
2548
2549       The command DUMPVARS displays the values of variables in  memory.   Its
2550       format is:
2551
2552       DUMPVARS [var...]
2553
2554       If you supply a space-separated list of variable names, the correspond‐
2555       ing variables are displayed.  If you do not supply a list of variables,
2556       then all variables in memory are displayed.  To dump a system variable,
2557       put its name in the list of variables to dump.  If you put a lone  dol‐
2558       lar  sign  in  the list of variables to dump, then all system variables
2559       will be dumped.
2560
2561       THE ERRMSG COMMAND
2562
2563       The ERRMSG command has the following format:
2564
2565       ERRMSG body
2566
2567       The body is passed through the substitution filter  (with  an  implicit
2568       trigger date of today()) and printed to the error output stream.  Exam‐
2569       ple:
2570
2571            IF !defined("critical_var")
2572                 ERRMSG You must supply a value for "critical_var"
2573                 EXIT
2574            ENDIF
2575
2576       THE EXIT COMMAND
2577
2578       The above example also shows the use of the EXIT command.  This  causes
2579       an  unconditional  exit  from  script  processing.   Any  queued  timed
2580       reminders are discarded.  If you are in calendar mode (described next),
2581       then the calendar processing is aborted.
2582
2583       If  you  supply  an  INT-type  expression after the EXIT command, it is
2584       returned to the calling program as the exit status.  Otherwise, an exit
2585       status of 99 is returned.
2586
2587       THE FLUSH COMMAND
2588
2589       This  command  simply  consists  of the word FLUSH on a line by itself.
2590       The command flushes the standard output and standard error streams used
2591       by Remind.  This is not terribly useful to most people, but may be use‐
2592       ful if you run Remind as a subprocess of another program, and  want  to
2593       use pipes for communication.
2594

CALENDAR MODE

2596       If you supply the -c, -s or -p command-line option, then Remind runs in
2597       "calendar mode."  In this mode, Remind interprets  the  script  repeat‐
2598       edly,  performing  one iteration through the whole file for each day in
2599       the calendar.  Reminders that trigger are saved  in  internal  buffers,
2600       and then inserted into the calendar in the appropriate places.
2601
2602       If  you  also  supply the -a option, then Remind will not include timed
2603       reminders in the calendar.
2604
2605       The -p option is used in conjunction with the Rem2PS program to produce
2606       a  calendar  in  PostScript format.  For example, the following command
2607       will send PostScript code to standard output:
2608
2609            remind -p .reminders | rem2ps
2610
2611       You can print a PostScript calendar by piping this to the lpr command.
2612
2613       If you have a reminder script called ".reminders", and you execute this
2614       command:
2615
2616            remind -c .reminders jan 1993
2617
2618       then Remind executes the script 31 times, once for each day in January.
2619       Each time it executes the script, it increments the value  of  today().
2620       Any  reminders  whose trigger date matches today() are entered into the
2621       calendar.
2622
2623       MSG and CAL-type reminders, by default, have their entire body inserted
2624       into  the  calendar.  RUN-type reminders are not normally inserted into
2625       the calendar.  However, if you enclose a portion of  the  body  in  the
2626       %"...%" sequence, only that portion is inserted.  For example, consider
2627       the following:
2628
2629            REM 6 Jan MSG %"David's birthday%" is %b
2630
2631       In the normal mode, Remind would print "David's birthday is today" on 6
2632       January.   However, in the calendar mode, only the text "David's birth‐
2633       day" is inserted into the box for 6 January.
2634
2635       If you explicitly use the %"...%" sequence in a RUN-type reminder, then
2636       the  text between the delimiters is inserted into the calendar.  If you
2637       use the sequence %"%" in a MSG or CAL-type reminder, then  no  calendar
2638       entry is produced for that reminder.
2639
2640       PRESERVING VARIABLES
2641
2642       Because  Remind  iterates through the script for each day in the calen‐
2643       dar, slow operations may severely reduce the speed of producing a  cal‐
2644       endar.
2645
2646       For  example, suppose you set the variables "me" and "hostname" as fol‐
2647       lows:
2648
2649            SET me shell("whoami")
2650            SET hostname shell("hostname")
2651
2652       Normally, Remind clears all variables between  iterations  in  calendar
2653       mode.   However, if certain variables are slow to compute, and will not
2654       change between iterations, you can "preserve"  their  values  with  the
2655       PRESERVE  command.   Also,  since  function  definitions  are preserved
2656       between calendar iterations, there is no need to redefine them on  each
2657       iteration.  Thus, you could use the following sequence:
2658
2659            IF ! defined("initialized")
2660                 set initialized 1
2661                 set me shell("whoami")
2662                 set hostname shell("hostname")
2663                 fset func(x) complex_expr
2664                 preserve initialized me hostname
2665            ENDIF
2666
2667       The  operation  is  as  follows:   On  the  first iteration through the
2668       script, "initialized" is not defined.  Thus, the  commands  between  IF
2669       and  ENDIF  are executed.  The PRESERVE command ensures that the values
2670       of initialized, me and hostname are  preserved  for  subsequent  itera‐
2671       tions.  On the next iteration, the commands are skipped, since initial‐
2672       ized has remained defined.  Thus, time-consuming operations that do not
2673       depend on the value of today() are done only once.
2674
2675       System  variables  (those whose names start with '$') are automatically
2676       preserved between calendar iterations.
2677
2678       Note that for efficiency, Remind caches the reminder  script  (and  any
2679       INCLUDEd files) in memory when producing a calendar.
2680
2681       Timed  reminders are sorted and placed into the calendar in time order.
2682       These are followed by non-timed reminders.  Remind automatically places
2683       the  time  of  timed reminders in the calendar according to the -b com‐
2684       mand-line option.  Reminders in calendar mode are sorted as if  the  -g
2685       option had been used; you can change the sort order in calendar mode by
2686       explicitly using the -g option to specify a different  order  from  the
2687       default.
2688
2689       REPEATED EXECUTION
2690
2691       If  you  supply  a repeat parameter on the command line, and do not use
2692       the -c, -p, or -s options, Remind operates in a similar manner to  cal‐
2693       endar  mode.   It repeatedly executes the reminder script, incrementing
2694       today() with each iteration.  The same rules about preserving variables
2695       and  function definitions apply.  Note that using repeat on the command
2696       line also enables the -q option and disables  any  -z  option.   As  an
2697       example,  if  you want to see how Remind will behave for the next week,
2698       you can type:
2699
2700            remind .reminders '*7'
2701
2702       If you want to print the dates of the next 1000 days, use:
2703
2704            (echo 'banner %'; echo 'msg [today()]%') | remind - '*1000'
2705

INITIALIZING VARIABLES ON THE COMMAND LINE

2707       The -i option is used to initialize variables  on  the  Remind  command
2708       line.   The  format  is -ivar=expr, where expr is any valid expression.
2709       Note that you may have to use quotes or escapes to  prevent  the  shell
2710       from  interpreting special characters in expr.  You can have as many -i
2711       options as you want on the command line,  and  they  are  processed  in
2712       order.   Thus,  if  a  variable  is defined in one -i option, it can be
2713       referred to by subsequent -i options.
2714
2715       Note that if you supply a date on the command line, it  is  not  parsed
2716       until all options have been processed.  Thus, if you use today() in any
2717       of the -i expressions, it will return the same value as realtoday() and
2718       not the date supplied on the command line.
2719
2720       Any  variables  defined  on  the command line are preserved as with the
2721       PRESERVE command.
2722
2723       You should not have any spaces between the  -i  option  and  the  equal
2724       sign;  otherwise,  strange  variable names are created that can only be
2725       accessed with the value() or defined() functions.
2726

MORE ABOUT POSTSCRIPT

2728       The PS and PSFILE  reminders  pass  PostScript  code  directly  to  the
2729       printer.   They  differ  in  that  the PS-type reminder passes its body
2730       directly to the PostScript output (after processing by the substitution
2731       filter)  while  the PSFILE-type's body should simply consist of a file‐
2732       name.  The Rem2PS program will open the file named in  the  PSFILE-type
2733       reminder, and include its contents in the PostScript output.
2734
2735       The  PostScript-type reminders for a particular day are included in the
2736       PostScript output in sorted order of priority.  Note that the order  of
2737       PostScript  commands has a major impact on the appearance of the calen‐
2738       dars.  For example, PostScript code to shade a calendar box will oblit‐
2739       erate  code  to draw a moon symbol if the moon symbol code is placed in
2740       the calendar first.  For this reason, you  should  not  provide  PS  or
2741       PSFILE-type  reminders with priorities; instead, you should ensure that
2742       they appear in the reminder script in the  correct  order.   PostScript
2743       code should draw objects working from the background to the foreground,
2744       so that foreground objects properly overlay background  ones.   If  you
2745       prioritize  these  reminders  and  run the script using descending sort
2746       order for priorities, the PostScript output will not work.
2747
2748       All of the PostScript code for a particular date is enclosed in a save-
2749       restore  pair.  However, if several PostScript-type reminders are trig‐
2750       gered for a single day, each section of PostScript is not enclosed in a
2751       save-restore  pair - instead, the entire body of included PostScript is
2752       enclosed.
2753
2754       PostScript-type reminders are executed by the PostScript printer before
2755       any  regular  calendar  entries.   Thus,  regular calendar entries will
2756       overlay the PostScript-type reminders, allowing you to create shaded or
2757       graphical backgrounds for particular days.
2758
2759       Before  executing  your  PostScript  code, the origin of the PostScript
2760       coordinate system is positioned to the bottom left-hand corner  of  the
2761       "box"  in  the calendar representing today().  This location is exactly
2762       in the middle of the intersection of the bottom and  left  black  lines
2763       delineating  the  box  -  you  may have to account for the thickness of
2764       these lines when calculating positions.
2765
2766       Several PostScript variables are available to the PostScript  code  you
2767       supply.   All distance and size variables are in PostScript units (1/72
2768       inch.)  The variables are:
2769
2770       LineWidth
2771              The width of the black grid lines making up the calendar.
2772
2773       Border The border between the center of the grid lines  and  the  space
2774              used  to  print calendar entries.  This border is normally blank
2775              space.
2776
2777       BoxWidth and BoxHeight
2778              The width and height of the calendar box, from  center-to-center
2779              of the black gridlines.
2780
2781       InBoxHeight
2782              The  height  from the center of the bottom black gridline to the
2783              top of the regular calendar entry area.  The space from here  to
2784              the top of the box is used only to draw the day number.
2785
2786       /DayFont, /EntryFont, /SmallFont, /TitleFont and /HeadFont
2787              The  fonts  used  to draw the day numbers, the calendar entries,
2788              the small calendars, the calendar title (month,  year)  and  the
2789              day-of-the-week headings, respectively.
2790
2791       DaySize, EntrySize, TitleSize and HeadSize
2792              The  sizes  of the above fonts.  (The size of the small calendar
2793              font is not defined here.)  For example, if you wanted to  print
2794              the  Hebrew date next to the regular day number in the calendar,
2795              use:
2796
2797            REM PS Border BoxHeight Border sub DaySize sub moveto \
2798               /DayFont findfont DaySize scalefont setfont \
2799               ([hebday(today())] [hebmon(today())]) show
2800
2801              Note how /DayFont and DaySize are used.
2802
2803       Note that if you supply PostScript code,  it  is  possible  to  produce
2804       invalid  PostScript files.  Always test your PostScript thoroughly with
2805       a PostScript viewer before sending it to the printer.  You  should  not
2806       use any document structuring comments in your PostScript code.
2807

DAEMON MODE

2809       If  you  use  the  -z  command-line option, Remind runs in the "daemon"
2810       mode.  In this mode, no "normal" reminders are issued.   Instead,  only
2811       timed  reminders are collected and queued, and are then issued whenever
2812       they reach their trigger time.
2813
2814       In addition, Remind wakes up every few minutes to check  the  modifica‐
2815       tion  date on the reminder script (the filename supplied on the command
2816       line.)  If Remind detects that the script has changed,  it  re-executes
2817       itself in daemon mode, and interprets the changed script.
2818
2819       In  daemon mode, Remind also re-reads the remind script when it detects
2820       that the system date has changed.
2821
2822       In daemon mode, Remind acts as if the -f option had been  used,  so  to
2823       run in the daemon mode in the background, use:
2824
2825            remind -z .reminders &
2826
2827       If  you  use  sh  or  bash,  you may have to use the "nohup" command to
2828       ensure that the daemon is not killed when you log out.
2829

SORTING REMINDERS

2831       The -g option causes Remind to sort reminders by trigger date, time and
2832       priority before issuing them.  Note that reminders are still calculated
2833       in the order encountered in the script.   However,  rather  than  being
2834       issued  immediately, they are saved in an internal buffer.  When Remind
2835       has finished processing the script, it issues the  saved  reminders  in
2836       sorted  order.  The -g option can be followed by up to three characters
2837       that must all be "a" or "d".  The first character  specifies  the  sort
2838       order  by  trigger date (ascending or descending), the second specifies
2839       the sort order by trigger time and the third specifies the  sort  order
2840       by priority.  The default is to sort all fields in ascending order.
2841
2842       In  ascending order, reminders are issued with the most imminent first.
2843       Descending order is the reverse.  Reminders are always sorted by  trig‐
2844       ger  date,  and reminders with the same trigger date are then sorted by
2845       trigger time.   Non-timed  reminders  are  always  issued  after  timed
2846       reminders  in this mode.  If two reminders have the same date and time,
2847       then the priority is used to break ties.  Reminders with the same date,
2848       time and priority are issued in the order they were encountered.
2849
2850       You can define a user-defined function called SORTBANNER that takes one
2851       DATE-type argument.  In sort mode, the following sequence happens:
2852
2853       If Remind notices that the next reminder to issue has a different trig‐
2854       ger  date  from  the  previous  one  (or  if  it is the first one to be
2855       issued), then SORTBANNER is called with the trigger date as  its  argu‐
2856       ment.   The  result is coerced to a string, and passed through the sub‐
2857       stitution filter with the appropriate trigger date.  The result is then
2858       displayed.
2859
2860       Here's an example - consider the following fragment:
2861
2862            # Switch off the normal banner
2863            BANNER %
2864            REM 11 March 1993 ++1 MSG Not so important
2865            REM 17 March 1993 ++7 MSG Way in the future
2866            REM 10 March 1993 MSG Important Reminder
2867            REM 11 March 1993 ++1 MSG Not so important - B
2868            FSET sortbanner(x) iif(x == today(), \
2869                 "***** THINGS TO DO TODAY *****", \
2870                 "----- Things to do %b -----")
2871
2872       Running this with the -gaa option on 10 March 1993 produces the follow‐
2873       ing output:
2874
2875            ***** THINGS TO DO TODAY *****
2876
2877            Important Reminder
2878
2879            ----- Things to do tomorrow -----
2880
2881            Not so important
2882
2883            Not so important - B
2884
2885            ----- Things to do in 7 days' time -----
2886
2887            Way in the future
2888
2889       You can use the args() built-in function to determine  whether  or  not
2890       SORTBANNER has been defined.  (This could be used, for example, to pro‐
2891       vide a default definition for SORTBANNER in a system-wide file included
2892       at the end of the user's file.)  Here's an example:
2893
2894            # Create a default sortbanner function if it hasn't already
2895            # been defined
2896            if args("sortbanner") != 1
2897                 fset sortbanner(x) "--- Things to do %b ---"
2898            endif
2899

MSGPREFIX() AND MSGSUFFIX()

2901       You can define two functions in your script called msgprefix() and msg‐
2902       suffix().  They should each accept one argument, a  number  from  0  to
2903       9999.
2904
2905       In normal mode, for MSG- and MSF-type reminders, the following sequence
2906       occurs when Remind triggers a reminder:
2907
2908       o      If msgprefix() is defined, it is evaluated with the priority  of
2909              the reminder as its argument.  The result is printed.  It is not
2910              passed through the substitution filter.
2911
2912       o      The body of the reminder is printed.
2913
2914       o      If msgsuffix() is defined, it is evaluated with the priority  of
2915              the reminder as its argument.  The result is printed.  It is not
2916              passed through the substitution filter.
2917
2918       Here's  an  example:   The  following  definition   causes   priority-0
2919       reminders to be preceded by "URGENT", and priority-6000 reminders to be
2920       preceded by "(not important)".
2921
2922            fset msgprefix(x) iif(x==0, "URGENT: ", \
2923                 x==6000, "(not important) ", "")
2924
2925       In Calendar Mode (with the -c, -s or -p options), an analogous pair  of
2926       functions  named calprefix() and calsuffix() can be defined.  They work
2927       with all reminders that produce an entry in the  calendar  (i.e.,  CAL-
2928       and possibly RUN-type reminders as well as MSG-type reminders.)
2929
2930       NOTES
2931
2932       Normally,  the  body  of  a  reminder is followed by a carriage return.
2933       Thus, the results of msgsuffix() will appear on the next line.  If  you
2934       don't  want  this, end the body of the reminder with a percentage sign,
2935       "%".  If you want a space between your reminders, simply include a car‐
2936       riage return (char(13)) as part of the msgsuffix() return value.
2937
2938       If  Remind has problems evaluating msgprefix(), msgsuffix() or sortban‐
2939       ner(), you will see a lot of error messages.  For an example  of  this,
2940       define the following:
2941
2942            fset msgprefix(x) x/0
2943

FOREIGN LANGUAGE SUPPORT

2945       Your  version  of  Remind  may have been compiled to support a language
2946       other than English.  This support may or may  not  be  complete  -  for
2947       example,  all  error  and usage messages may still be in English.  How‐
2948       ever, at a minimum, foreign-language versions  of  Remind  will  output
2949       names  of  months and weekdays in the foreign language.  Also, the sub‐
2950       stitution mechanism will substitute constructs suitable for the foreign
2951       language rather than for English.
2952
2953       A  foreign-language version of Remind will accept either the English or
2954       foreign-language names of weekdays and months  in  a  reminder  script.
2955       However,  for  compatibility between versions of Remind, you should use
2956       only the English names in your scripts.  Also, if your  C  compiler  or
2957       run-time  libraries  are not "8-bit clean" or don't understand the ISO-
2958       Latin character set, month or day names with accented letters  may  not
2959       be recognized.
2960

THE HEBREW CALENDAR

2962       Remind  has support for the Hebrew calendar, which is a luni-solar cal‐
2963       endar.  This allows  you  to  create  reminders  for  Jewish  holidays,
2964       jahrzeits (anniversaries of deaths) and smachot (joyous occasions.)
2965
2966       THE HEBREW YEAR
2967
2968       The  Hebrew  year  has 12 months, alternately 30 and 29 days long.  The
2969       months are: Tishrey, Heshvan, Kislev, Tevet, Shvat, Adar, Nisan,  Iyar,
2970       Sivan,  Tamuz,  Av  and  Elul.   In Biblical times, the year started in
2971       Nisan, but Rosh Hashana (Jewish New Year) is now celebrated on the  1st
2972       and 2nd of Tishrey.
2973
2974       In  a  cycle  of 19 years, there are 7 leap years, being years 3, 6, 8,
2975       11, 14, 17 and 19 of the cycle.  In a leap year, an extra month  of  30
2976       days is added before Adar.  The two Adars are called Adar A and Adar B.
2977
2978       For  certain  religious  reasons,  the  year  cannot start on a Sunday,
2979       Wednesday or Friday.  To adjust for this, a day is taken off Kislev  or
2980       added  to Heshvan.  Thus, a regular year can have from 353 to 355 days,
2981       and a leap year from 383 to 385.
2982
2983       When Kislev or Heshvan is short, it is called chaser, or lacking.  When
2984       it is long, it is called shalem, or full.
2985
2986       The  Jewish  date  changes  at sunset.  However, Remind will change the
2987       date at midnight, not sunset.  So in the period between sunset and mid‐
2988       night,  Remind  will  be a day earlier than the true Jewish date.  This
2989       should not be much of a problem in practice.
2990
2991       The computations for the Jewish calendar  were  based  on  the  program
2992       "hdate"  written  by Amos Shapir of the Hebrew University of Jerusalem,
2993       Israel.  He also supplied the preceding explanation of the calendar.
2994
2995       HEBREW DATE FUNCTIONS
2996
2997       hebday(d_date)
2998              Returns the day of the Hebrew month corresponding  to  the  date
2999              parameter.   For  example, 12 April 1993 corresponds to 21 Nisan
3000              5753.  Thus, hebday('1993/04/12') returns 21.
3001
3002       hebmon(d_date)
3003              Returns the name of the Hebrew month corresponding to date.  For
3004              example, hebmon('1993/04/12') returns "Nisan".
3005
3006       hebyear(d_date)
3007              Returns  the  Hebrew  year  corresponding to date.  For example,
3008              hebyear('1993/04/12') returns 5753.
3009
3010       hebdate(i_day, s_hebmon [,id_yrstart [,i_jahr [,i_aflag]]])
3011              The hebdate() function is the most complex of the Hebrew support
3012              functions.   It  can  take  from 2 to 5 arguments.  It returns a
3013              DATE corresponding to the Hebrew date.
3014
3015              The day parameter can range from 1 to 30, and specifies the  day
3016              of the Hebrew month.  The hebmon parameter is a string that must
3017              name one of the Hebrew months specified above.   Note  that  the
3018              month must be spelled out in full, and use the English translit‐
3019              eration shown previously.  You can also  specify  "Adar  A"  and
3020              "Adar B."  Month names are not case-sensitive.
3021
3022              The  yrstart parameter can either be a DATE or an INT.  If it is
3023              a DATE, then the hebdate() scans for the first Hebrew date on or
3024              after that date.  For example:
3025
3026                        hebdate(15, "Nisan", '1990/01/01')
3027
3028              returns  1990/03/30,  because that is the first occurrence of 15
3029              Nisan on or after 1 January 1990.
3030
3031              If yrstart is an INT, it is interpreted as a Hebrew year.  Thus:
3032
3033                        hebdate(22, "Kislev", 5756)
3034
3035              returns 1995/12/15, because that date corresponds to 22  Kislev,
3036              5756.   Note  that  none  of the Hebrew date functions will work
3037              with dates outside Remind's normal range for dates.
3038
3039              If yrstart is not supplied, it defaults to today().
3040
3041              The jahr modifies the behaviour of hebdate() as follows:
3042
3043              If jahr is 0 (the default), then hebdate() keeps scanning  until
3044              it  finds  a  date  that exactly satisfies the other parameters.
3045              For example:
3046
3047                        hebdate(30, "Adar A", 1993/01/01)
3048
3049              returns 1995/03/02, corresponding to 30 Adar  A,  5755,  because
3050              that  is the next occurrence of 30 Adar A after 1 January, 1993.
3051              This behaviour  is  appropriate  for  Purim  Katan,  which  only
3052              appears in leap years.
3053
3054              If jahr is 1, then the date is modified as follows:
3055
3056              o      30 Heshvan is converted to 1 Kislev in years when Heshvan
3057                     is chaser
3058
3059              o      30 Kislev is converted to 1 Tevet in years when Kislev is
3060                     chaser
3061
3062              o      30 Adar A is converted to 1 Nisan in non-leapyears
3063
3064              o      Other  dates in Adar A are moved to the corresponding day
3065                     in Adar in non-leapyears
3066
3067              This behaviour is appropriate for smachot (joyous occasions) and
3068              for some jahrzeits - see "JAHRZEITS."
3069
3070              if jahr is 2, then the date is modified as follows:
3071
3072              o      30  Kislev  and 30 Heshvan are converted to 29 Kislev and
3073                     29 Heshvan, respectively, if the month is chaser
3074
3075              o      30 Adar A is converted to 30 Shvat in non-leapyears
3076
3077              o      Other dates in Adar A are moved to the corresponding  day
3078                     in Adar in non-leapyears
3079
3080              if  jahr  is not 0, 1, or 2, it is interpreted as a Hebrew year,
3081              and the behaviour is calculated as described in  the  next  sec‐
3082              tion, "JAHRZEITS."
3083
3084              The  aflag  parameter modifies the behaviour of the function for
3085              dates in Adar during leap years.  The  aflag  is  only  used  if
3086              yrstart is a DATE type.
3087
3088              The  aflag only affects date calculations if hebmon is specified
3089              as "Adar".  In leap years, the following algorithm is followed:
3090
3091              o      If aflag is 0, then the date  is  triggered  in  Adar  B.
3092                     This is the default.
3093
3094              o      If  aflag  is  1,  then  the date is triggered in Adar A.
3095                     This may be appropriate for jahrzeits  in  the  Ashkenazi
3096                     tradition; consult a rabbi.
3097
3098              o      If  aflag is 2, then the date is triggered in both Adar A
3099                     and Adar B of  a  leap  year.   Some  Ashkenazim  perform
3100                     jahrzeit in both Adar A and Adar B.
3101
3102       JAHRZEITS
3103
3104       A  jahrzeit  is a yearly commemoration of someone's death.  It normally
3105       takes place on the anniversary of the death,  but  may  be  delayed  if
3106       burial is delayed - consult a rabbi for more information.
3107
3108       In addition, because some months change length, it is not obvious which
3109       day the anniversary of a death is.  The following rules are used:
3110
3111       o      If the death occurred on 30 Heshvan, and  Heshvan  in  the  year
3112              after  the  death is chaser, then the jahrzeit is observed on 29
3113              Heshvan  in  years  when  Heshvan  is  chaser.   Otherwise,  the
3114              yahrzeit is observed on 1 Kislev when Heshvan is chaser.
3115
3116       o      If the death occurred on 30 Kislev, and Kislev in the year after
3117              the death is chaser, then the jahrzeit is observed on 29  Kislev
3118              in  years  when  Kislev  is  chaser.  Otherwise, the yahrzeit is
3119              observed on 1 Tevet when Kislev is chaser.
3120
3121       o      If the death occurred on 1-29 Adar A, it  is  observed  on  1-29
3122              Adar in non-leapyears.
3123
3124       o      If  the  death occurred on 30 Adar A, it is observed on 30 Shvat
3125              in a non-leapyear.
3126
3127       Specifying a Hebrew year for the jahr parameter causes the correct  be‐
3128       haviour  to be selected for a death in that year.  You may also have to
3129       specify aflag, depending on your tradition.
3130
3131       The jahrzeit information was supplied by Frank Yellin, who quoted  "The
3132       Comprehensive Hebrew Calendar" by Arthur Spier, and "Calendrical Calcu‐
3133       lations" by E. M. Reingold and Nachum Dershowitz.
3134

OUT-OF-BAND REMINDERS

3136       The SPECIAL keyword is used to transmit  "out-of-band"  information  to
3137       Remind  backends,  such as tkremind or Rem2PS.  They are used only when
3138       piping data from a remind -p line.  (Note that the COLOR special is  an
3139       exception;  it  downgrades  to the equivalent of MSG in remind's normal
3140       mode of operation.)
3141
3142       The various SPECIALs recognized are particular for each  backend;  how‐
3143       ever, there are three SPECIALs that all backends should attempt to sup‐
3144       port.  They are currently supported by Rem2PS, tkremind and rem2html.
3145
3146       The SHADE special replaces the psshade() function.  Use it like this:
3147            REM Sat Sun SPECIAL SHADE 128
3148            REM Mon SPECIAL SHADE 255 0 0
3149       The SHADE keyword is followed by either one or three numbers, from 0 to
3150       255.   If  one  number  is  supplied, it is interpreted as a grey-scale
3151       value from black (0) to white (255).  If three  numbers  are  supplied,
3152       they  are  interpreted  as  RGB  components from minimum (0) to maximum
3153       (255).  The example above shades weekends a fairly dark grey and  makes
3154       Mondays  a  fully-saturated  red.   (These shadings appear in calendars
3155       produced by Rem2PS, tkremind and rem2html.)
3156
3157       The MOON special replaces the psmoon() function.  Use it like this:
3158            REM [trigger(moondate(0))] SPECIAL MOON 0
3159            REM [trigger(moondate(1))] SPECIAL MOON 1
3160            REM [trigger(moondate(2))] SPECIAL MOON 2
3161            REM [trigger(moondate(3))] SPECIAL MOON 3
3162       These draw little moons on the various calendars.  The complete  syntax
3163       of the MOON special is as follows:
3164            ... SPECIAL MOON phase moonsize fontsize msg
3165
3166       Phase  is  a  number from 0 to 3, with 0 representing a new moon, 1 the
3167       first quarter, 2 a full moon and 3 the last quarter.
3168
3169       moonsize is the diameter in PostScript units of the moon to  draw.   If
3170       omitted or supplied as -1, the backend chooses an appropriate size.
3171
3172       fontsize is the font size in PostScript units of the msg
3173
3174       Msg is additional text that is placed near the moon glyph.
3175
3176       Note  that  only the Rem2PS backend supports moonsize and fontsize; the
3177       other backends use fixed sizes.
3178
3179       The COLOR special lets you place colored  reminders  in  the  calendar.
3180       Use it like this:
3181
3182            REM ... SPECIAL COLOR 255 0 0 This is a bright red reminder
3183            REM ... SPECIAL COLOR 0 128 0 This is a dark green reminder
3184
3185       Immediately  following  COLOR  should  be three decimal numbers ranging
3186       from 0 to 255 specifying red, green and blue intensities, respectively.
3187       The rest of the line is the text to put in the calendar.
3188
3189       The  COLOR special is "doubly special", because in its normal operating
3190       mode, remind treats a COLOR special just like a MSG-type reminder.
3191

MISCELLANEOUS

3193       COMMAND ABBREVIATIONS
3194
3195       The following tokens can be abbreviated:
3196
3197       o      REM can be omitted - it is implied if no other valid command  is
3198              present.
3199
3200       o      CLEAR-OMIT-CONTEXT --> CLEAR
3201
3202       o      PUSH-OMIT-CONTEXT --> PUSH
3203
3204       o      POP-OMIT-CONTEXT --> POP
3205
3206       o      DUMPVARS --> DUMP
3207
3208       o      BANNER --> BAN
3209
3210       o      INCLUDE --> INC
3211
3212       o      SCANFROM --> SCAN
3213
3214       NIFTY EXAMPLES
3215
3216       This section is a sampling of what you can do with Remind.
3217
3218            REM 5 Feb 1991 AT 14:00 +45 *30 \
3219            RUN mail -s "Meeting at %2" $LOGNAME </dev/null &
3220
3221       On  5 February, 1991, this reminder will mail you reminders of a 2:00pm
3222       meeting at 1:15, 1:45 and 2:00.  The subject of the mail  message  will
3223       be "Meeting at 2:00pm" and the body of the message will be blank.
3224
3225            REM AT 17:00 RUN echo "5:00pm - GO HOME!" | xless -g +0+0 &
3226
3227       This  reminder  will  pop  up an xless window at 5:00pm every day.  The
3228       xless window will contain the line "5:00pm - GO HOME!"
3229
3230            REM AT 23:59 RUN (sleep 120; remind -a [filename()]) &
3231
3232       This reminder will run at one minute to midnight.  It will cause a  new
3233       Remind  process  to start at one minute past midnight.  This allows you
3234       to have a continuous reminder service so you can work through the night
3235       and still get timed reminders for early in the morning.  Note that this
3236       trick is no longer necessary, providing you run Remind in daemon mode.
3237
3238            remind -c12 /dev/null Jan 1993
3239
3240       This invocation of Remind will cause it to print a calendar  for  1993,
3241       with all entries left blank.
3242
3243            REM CAL [trigdate()-date(year(trigdate()), 1, 1)+1]
3244
3245       This example puts an entry in each box of a calendar showing the number
3246       (1-365 or 366) of the day of the year.
3247
3248            REM Tue 2 Nov SATISFY (year(trigdate())%4) == 0
3249            IF trigvalid()
3250                 REM [trigger(trigdate())] ++5 MSG \
3251                 U.S. Presidential Election!!
3252            ENDIF
3253
3254       This example warns you 5 days ahead of each American presidential elec‐
3255       tion.   The  first  REM  command calculates the first Tuesday after the
3256       first Monday in November.  (This is equivalent to the first Tuesday  on
3257       or after 2 November.)  The SATISFY clause ensures that the trigger date
3258       is issued only in election years, which are multiples of 4.  The second
3259       REM command actually issues the reminder.
3260
3261       DETAILS ABOUT TRIGGER COMPUTATION
3262
3263       Here  is a conceptual description of how triggers are calculated.  Note
3264       that Remind actually uses a much  more  efficient  procedure,  but  the
3265       results are the same as if the conceptual procedure had been followed.
3266
3267       Remind starts from the current date (that is, the value of today()) and
3268       scans forward, examining each day one at a time until it finds  a  date
3269       that  satisfies  the  trigger,  or  can prove that no such dates (on or
3270       later than today()) exist.
3271
3272       If Remind is  executing  a  SATISFY-type  reminder,  it  evaluates  the
3273       expression with trigdate() set to the date found above.  If the expres‐
3274       sion evaluates to zero or the null string, Remind continues  the  scan‐
3275       ning procedure described above, starting with the day after the trigger
3276       found above.
3277
3278       The SCANFROM clause (having a syntax similar to UNTIL) can  modify  the
3279       search  strategy used.  In this case, Remind begins the scanning proce‐
3280       dure at scan_date, which is the date specified in the SCANFROM  clause.
3281       For example:
3282
3283            REM Mon 1 SCANFROM 17 Jan 1992 MSG Foo
3284
3285       The example above will always have a trigger date of Monday, 3 February
3286       1992.  That is because Remind starts scanning from 17 January 1992, and
3287       stops scanning as soon as it hits a date that satisfies "Mon 1."
3288
3289       The  main  use of SCANFROM is in situations where you want to calculate
3290       the positions of floating holidays.  Consider the  Labour  Day  example
3291       shown  much  earlier.  Labour Day is the first Monday in September.  It
3292       can move over a range of 7 days.  Consider the following sequence:
3293
3294            REM Mon 1 Sept SCANFROM [trigger(today()-7)] SATISFY 1
3295            OMIT [trigger(trigdate())]
3296
3297            REM Mon AFTER MSG Hello
3298
3299       The SCANFROM clause makes sure that Remind begins scanning from 7  days
3300       before  the current date.  This ensures that Labour Day for the current
3301       year will continue to be triggered until 7 days after it has  occurred.
3302       This allows you to safely use the AFTER keyword as shown.
3303
3304       In  general,  use SCANFROM as shown for safe movable OMITs.  The amount
3305       you should scan back by (7 days in the example above)  depends  on  the
3306       number  of possible consecutive OMITted days that may occur, and on the
3307       range of the movable holiday.  Generally, a value of 7 is safe.
3308
3309       The FROM clause operates almost like the  counterpoint  to  UNTIL.   It
3310       prevents  the reminder from triggering before the FROM date.  For exam‐
3311       ple, the following reminder:
3312
3313            REM Mon Thu FROM 23 Jul 2007 UNTIL 2 Aug 2007 MSG Test
3314
3315       will trigger on Mondays and Thursdays between 23 July 2007 and 2 August
3316       2007 inclusive.
3317
3318       FROM  is  really just syntactic sugar; you could implement the reminder
3319       above as follows:
3320
3321            REM Mon Thu SCANFROM [trigger(max(today(), '2007-07-23'))] \
3322                   UNTIL 2 Aug 2007 MSG Test
3323
3324       but that's a lot  harder  to  read.   Internally,  Remind  treats  FROM
3325       exactly as illustrated using SCANFROM.  For that reason, you cannot use
3326       both FROM and SCANFROM.
3327
3328       Note that if you use one REM command to calculate a trigger date,  per‐
3329       form  date calculations (addition or subtraction, for example) and then
3330       use the modified date in a subsequent REM command, the results may  not
3331       be what you intended.  This is because you have circumvented the normal
3332       scanning mechanism.  You should try to write REM commands that  compute
3333       trigger  dates  that can be used unmodified in subsequent REM commands.
3334       The file "defs.rem" that comes with the  Remind  distribution  contains
3335       examples.
3336
3337       DETAILS ABOUT TRIGVALID()
3338
3339       The  trigvalid() function returns 1 if Remind could find a trigger date
3340       for the previous REM or IFTRIG command.  More specifically, it  returns
3341       1  if  Remind finds a date not before the starting date of the scanning
3342       that satisfies the trigger.  In addition, there is one special case  in
3343       which trigvalid() returns 1 and trigdate() returns a meaningful result:
3344
3345       If  the REM or IFTRIG command did not contain an UNTIL clause, and con‐
3346       tained all of the day, month and year components, then Remind will cor‐
3347       rectly  compute  a  trigger  date,  even if it happens to be before the
3348       start of scanning.  Note that this behaviour is not true  for  versions
3349       of Remind prior to 03.00.01.
3350

AUTHOR

3352       Remind   is   now   supported   by   Roaring   Penguin   Software  Inc.
3353       (http://www.roaringpenguin.com)
3354
3355       David F. Skoll <dfs@roaringpenguin.com> wrote Remind.   The  moon  code
3356       was copied largely unmodified from "moontool" by John Walker.  The sun‐
3357       rise and sunset functions use ideas from programs by  Michael  Schwartz
3358       and  Marc  T.  Kaufman.   The  Hebrew  calendar  support was taken from
3359       "hdate" by Amos Shapir.  OS/2 support was  done  by  Darrel  Hankerson,
3360       Russ  Herman,  and  Norman  Walsh.  The supported foreign languages and
3361       their translators are listed below.  Languages marked  "complete"  sup‐
3362       port error messages and usage instructions in that language; all others
3363       only support the substitution filter mechanism and month/day names.
3364
3365       German -- Wolfgang Thronicke
3366
3367       Dutch -- Willem Kasdorp and Erik-Jan Vens
3368
3369       Finnish -- Mikko Silvonen (complete)
3370
3371       French -- Laurent Duperval (complete)
3372
3373       Norwegian -- Trygve Randen
3374
3375       Danish -- Mogens Lynnerup
3376
3377       Polish -- Jerzy Sobczyk (complete)
3378
3379       Brazilian Portuguese -- Marco Paganini (complete)
3380
3381       Italian -- Valerio Aimale
3382
3383       Romanian -- Liviu Daia
3384
3385       Spanish -- Rafa Couto
3386
3387       Icelandic -- Björn Davíðsson
3388

BUGS

3390       There's no good reason why read-only system variables  are  not  imple‐
3391       mented  as  functions,  or  why functions like version(), etc.  are not
3392       implemented as read-only system variables.
3393
3394       Hebrew dates in Remind change at midnight instead of sunset.
3395
3396       Language should be selectable at  run-time,  not  compile-time.   Don't
3397       expect this to happen soon!  Remind has some built-in limits (for exam‐
3398       ple, number of global OMITs.)
3399

BIBLIOGRAPHY

3401       Nachum Dershowitz and Edward M. Reingold,  "Calendrical  Calculations",
3402       Software-Practice and Experience, Vol. 20(9), Sept. 1990, pp 899-928.
3403
3404       L.  E.  Doggett,  Almanac  for  computers  for  the year 1978, Nautical
3405       Almanac Office, USNO.
3406
3407       Richard Siegel and Michael and Sharon Strassfeld, The First Jewish Cat‐
3408       alog, Jewish Publication Society of America.
3409

SEE ALSO

3411       rem, rem2ps, tkremind
3412
3413
3414
34154th Berkeley Distribution         1 July 2007                        REMIND(1)
Impressum