 |
Index for Section 4 |
|
 |
Alphabetical listing for M |
|
 |
Bottom of page |
|
mh-format(4)
NAME
mh-format - Format file for the MH message system
DESCRIPTION
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
on.
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
processed. 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: %<, %| and %>. These correspond to if-then-
else constructs.
There are two syntaxes allowed by these control escapes. The first is:
%<(function)Command-string%>
%<{component}Command-String%>
If the function or component is non-zero (for integer-valued escapes) or
non-empty (for string-valued escapes), everything up to the corresponding
%> is interpreted. Otherwise, skip to the next %> and begin interpreting
again.
The second form of syntax is as follows:
%<(function)Then-Command-String%|Else-Command-String%>
%<{component}Then-Command-String%|Else-Command-String%>
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 %>
character.
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
contents 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
provided, 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
rendering
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
arguments 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.
RESTRICTIONS
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.
EXAMPLES
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:
%02(mon{date})/%02(mday{date})
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.
Next:
%<(mymbox{from})To:%14(friendly{to})
If the message is from me, print To: followed by a user-friendly rendering
of the first address in the To: field.
%|%17(friendly{from})%>
If the message is not from me, then the From: address is printed. And
finally:
%{subject}%<{body}<<%{body}%>
The subject and initial body are printed preceded by the string <<.
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
/usr/lib/mh/scan.timely.
RELATED INFORMATION
scan(1), ap(8), dp(8)
 |
Index for Section 4 |
|
 |
Alphabetical listing for M |
|
 |
Top of page |
|