Switch to SpeakEasy.net DSL

The Modular Manual Browser

Home Page
Manual: (OSF1-V5.1-alpha)
Apropos / Subsearch:
optional field

mh-format(4)							 mh-format(4)

  mh-format - Format file for the MH message system


  Several MH commands utilize either a format string or	a format file during
  their	execution.  For	example, scan(1) uses a	format string which specifies
  how scan should generate the scan listing for	each message; repl(1) uses a
  format file which directs it how to generate the reply to a message, and so

  This reference page describes	how to write new format	commands or modify
  existing ones.  You should not attempt this unless you are an	experienced
  MH user.

  A format string is similar to	a printf string, but uses multi-letter
  escapes.  The	rest of	this reference page assumes a knowledge	of the printf
  routine.  When specifying a string, the usual	C backslash characters are
  honored: \b, \f, \n, \r and \t.  Continuation	lines in format	files end
  with \ followed by the newline character.

  When an escape is interpreted	and the	result is immediately printed, you
  can specify an optional field	width to print the field in exactly a given
  number of characters.	 A numeric escape, such	as "%4(size)", will print at
  most 4 digits	of the value.  Any overflow is marked by a ? in	the first
  position, for	example	?123. A	string escape, such as "%4(me)", will print
  the first four characters of the string.  In both cases, short fields	are
  padded at the	right, usually with a blank.  If the field width argument
  begins with a	zero, for example "%04(size)", the fill	character is a zero.

  The interpretation model is based on a simple	machine	with two registers,
  num and str.	The former contains an integer value, the latter a string
  value.  When an escape is processed, if it requires an argument, it reads
  the current value of either num or str; and, if it returns a value, it
  writes either	num or str.

  Escapes are of three types: components, functions, and control.

  Component Escapes

  A component escape represents	a header field in the message being pro-
  cessed.  It is written {name}, where the name	is the name of the header
  field.  For example, {date} refers to	the Date: field	of the message.

  The value of a component escape is the content of the	named field.  This is
  always a string.  For	example, the header of an unsent message might look
  as follows:

       To: smith@local
       cc: davis
       Subject:	tomorrow's meeting

  In this example, the value of	the component escape {subject} is the string
  "tomorrow's meeting".

  Control Escapes

  A control escape is one of: %<&lt;, %| and %>&gt;.  These correspond to if-then-
  else constructs.

  There	are two	syntaxes allowed by these control escapes.  The	first is:


  If the function or component is non-zero (for	integer-valued escapes)	or
  non-empty (for string-valued escapes), everything up to the corresponding
  %>&gt; is	interpreted.  Otherwise, skip to the next %>&gt; and begin interpreting

  The second form of syntax is as follows:


  If the function or component is non-zero or non-null,	the Then-Command-
  String is interpreted.  Otherwise, skip to %|	and interpret the Else-
  Command-String.  Only	one string is ever interpreted;	if the first string
  is interpreted, the system skips from	the %| control escape to the %>&gt;	char-

  Function Escapes

  A function escape is specified as %(name), and is statically defined.

  Most functions expect	an argument of a particular type.  In the tables of
  functions that follow, these types are referred to:

  literal   A literal number or	string;	for example, %(func 1234) takes	the
	    number 1234	as its argument.

  comp	    Any	header component; for example, %(func{from}) takes the con-
	    tents of the From: header field as an argument.

  expr	    An optional	component, function or string, perhaps nested.	For
	    example, %(func (func2{comp})) takes the return value of the
	    function (func2{comp}) as its argument.  If	no argument is pro-
	    vided, the function	will read either the num or the	str register,
	    as appropriate.

  Functions return three types of values: string, integer, and,	for those
  functions which return a true	or false status, boolean.  In the tables that
  follow, str and num represent	the values stored in these registers. arg
  represents the value of the argument supplied	to the function.

  The following	table lists the	function escapes:

  Escape     Argument	Returns	  Interpretation
  msg			integer	  message number
  cur			integer	  message is current
  size			integer	  size of message
  strlen		integer	  length of str
  width			integer	  output buffer	size in	bytes
  charleft   integer	integer	  space	left in	output buffer
  timenow		integer	  seconds since	the epoch
  me			string	  the user's mailbox
  eq	     literal	integer	  num == arg
  ne	     literal	integer	  num != arg
  gt	     literal	integer	  num >	arg
  match	     literal	boolean	  str contains arg
  amatch     literal	boolean	  str starts with arg
  plus			integer	  arg plus num
  minus			integer	  arg minus num
  divide     literal	integer	  num divided by arg
  num	     literal	integer	  Set num to arg
  lit	     literal	integer	  Set str to arg
  nonzero    expr	integer	  num is non-zero
  zero	     expr	integer	  num is zero
  null	     expr	integer	  str is empty
  nonnull    expr	integer	  str is non-empty
  void	     expr		  Set str or num
  comp	     comp	string	  Set str to component text
  compval    comp	integer	  num set to atoi(str)
  trim	     expr		  trim trailing	white space from str
  putstr     expr		  print	str
  putstrf    expr		  print	str in a fixed width
  putnum     expr		  print	num
  putnum     expr		  print	num in a fixed width

  The following	functions require a date component as an argument:

  Escape       Argument	  Returns   Interpretation
  sec	       date	  integer   seconds of the minute
  min	       date	  integer   minutes of the day
  hour	       date	  integer   hours of the day (24 hour clock)
  wday	       date	  integer   day	of the week (Sunday=0)
  day	       date	  string    day	of the week
  weekday      date	  string    day	of the week (long)
  sday	       date	  integer   day	of the week known
				    1 for explicit in date
				    0 for implicit
				    -1 for unknown
  mday	       date	  integer   day	of the month
  yday	       date	  integer   day	of the year
  mon	       date	  integer   month of the year
  month	       date	  string    month of the year (abbreviated)
  lmonth       date	  string    month of the year (long form)
  year	       date	  integer   year of the	century
  zone	       date	  integer   timezone in	hours
  tzone	       date	  string    timezone as	a string
  szone	       date	  integer   timezone explicit?
				    1 for explicit
				    0 for implicit
				    -1 for unknown
  date2local   date		    coerce date	to local timezone
  date2gmt     date		    coerce date	to GMT
  dst	       date	  integer   daylight savings in	effect?
  clock	       date	  integer   seconds since the epoch
  rclock       date	  integer   seconds prior to current time
  tws	       date	  string    official RFC 822 rendering of the date
  pretty       date	  string    a more user-friendly rendering
  nodate       date		    str	could not be parsed as a date

  The following	functions require an address component as an argument.	Some
  functions return a value based on the	first address in the field only.
  These	are indicated by the note (first only).

  Escape       Argument	  Returns   Interpretation
  proper       addr	  string    official RFC 822 rendering
				    of the address
  friendly     string	  string    a more user-friendly
  pers	       addr	  string    the	personal name (first only)
  note	       addr	  string    commentary text (first only)
  mbox	       addr	  string    the	local part of the address
				    (first only)
  mymbox       addr		    does the address refer to
				    the	user's mailbox?
				    (0=no, 1=yes)
  host	       addr	  string    the	domain part of the address
				    (first only)
  nohost       addr	  integer   no host was	present	in the address
				    (first only)
  type	       addr	  integer   the	type of	host
				    -1 for uucp
				    0 for local
				    1 for network
				    2 for unknown
  path	       addr	  string    the	route part of the address
				    (first only)
  ingrp	       addr	  integer   the	address	appeared inside	a group
				    (first only)
  gname	       addr	  string    name of the	group (first only)
  formataddr   expr		    append arg to str as
				    an address list
  putaddr      literal		    print str address list with	arg
				    as an optional label; get line width
				    from num

  Some functions that print their arguments can	be controlled by giving	field
  width	arguments.  The	functions (putnumf) and	(putstrf) print	their argu-
  ments	as specified by	the field width	arguments.  So %06(putnumf(size))
  will print the message size in six digits, filled with leading zeros;
  %14(putsrtf{from}) will print	the From: header field in 14 characters, with
  trailing spaces as required.	With (putstrf),	supplying a negative field
  width	will cause the string to be right-justified within the field.  The
  functions (putnum) and (putstr) ignore any field width arguments, and	print
  their	arguments in the minimum number	of characters required.


  When the friendly format for addresses is used, addresses longer than	about
  180 characters are truncated to an empty string.  This means that such
  addresses will not appear in the scan	display.

  The function (mymbox{comp}) checks each of the addresses in the named
  header component {comp} against the user's mailbox name, and against any
  other	mailboxes listed in the	Alternate-Mailboxes entry in the user's
  .mh_profile.	It returns true	if any of the address matches.	However, it
  also returns true if the named {comp}	header field is	not present. If
  necessary, you can use the (null) or (nonnull) functions to test explicitly
  for the presence of the field.


  The default format string for	scan follows.  This has	been divided into
  several pieces for readability.  The first part is:

       %4(msg)%<(cur)+%| %>%<{replied}-%| %>

  This means that the message number should be printed in four digits; if the
  message is the current message then a	+ is printed.  If the message is not
  the current message, then a space is printed.	 If a Replied: field is
  present, a - is printed.  If no Replied: field is present, then a space is
  printed.  Next:


  The month and	date are printed in two	digits (zero filled).  Next:

       %<{date}	%|*>

  If no	Date: field is present,	then a * is printed, otherwise a space.


  If the message is from me, print To: followed	by a user-friendly rendering
  of the first address in the To: field.


  If the message is not	from me, then the From:	address	is printed.  And


  The subject and initial body are printed preceded by the string <&lt;<&lt;.

  Although this	seems complicated, this	method is flexible enough to extract
  individual fields and	print them in any format the user desires.

  If the -form formatfile switch is given with the scan	command, it will
  treat	each line in the named file as a format	string,	and act	accordingly.
  This lets the	user develop template scan listing formats.  Some examples
  can be found in /usr/lib/mh/scan.time, /usr/lib/mh/scan.size,	and


  scan(1), ap(8), dp(8)