5 .\" include the -mh macro file
8 .TH MH-FORMAT %manext5% MH.6.8 [%nmhversion%]
10 mh-format \- format file for nmh message system
14 some \fInmh\fR commands
17 Several \fInmh\fR commands utilize either a \fIformat\fR string or a
18 \fIformat\fR file during their execution. For example, \fIscan\fR\0(1)
19 uses a format string which directs it how to generate the scan listing
20 for each message; \fIrepl\fR\0(1) uses a format file which directs it
21 how to generate the reply to a message, and so on.
23 Format strings are designed to be efficiently parsed by \fInmh\fR
24 which means they are not necessarily simple to write and understand.
25 This means that novice, casual, or even advanced users of \fInmh\fR
26 should not have to deal with them.
28 There are a few alternate scan listing formats available
29 in %etcdir%/scan.time, %etcdir%/scan.size, and %etcdir%/scan.timely.
30 Look in %etcdir% for other \fIscan\fR and \fIrepl\fR format files which
31 may have been written at your site.
33 It suffices to have your local \fInmh\fR expert actually write new format
34 commands or modify existing ones. This manual section explains how to
35 do that. Note: familiarity with the C \fIprintf\fR routine is assumed.
37 A format string consists of ordinary text, and special multi-character
38 \fIescape\fR sequences which begin with `%'. When specifying a format
39 string, the usual C backslash characters are honored: `\\b', `\\f',
40 `\\n', `\\r', and `\\t'. Continuation lines in format files end with
41 `\\' followed by the newline character.
43 .\" TALK ABOUT SYNTAX FIRST, THEN SEMANTICS
44 There are three types of \fIescape\fR sequences: header
45 \fIcomponents\fR, built-in \fIfunctions\fR, and flow \fIcontrol\fR.
47 A \fIcomponent\fR escape is specified as `%{\fIcomponent\fR\^}', and
48 exists for each header found in the message being processed. For example
49 `%{date}' refers to the \*(lqDate:\*(rq field of the appropriate message.
50 All component escapes have a string value. Normally, component values are
51 compressed by converting any control characters (tab and newline included)
52 to spaces, then eliding any leading or multiple spaces. However, commands
53 may give different interpretations to some component escapes; be sure
54 to refer to each command's manual entry for complete details.
56 A \fIfunction\fR escape is specified as `%(\fIfunction\fR\^)'.
57 All functions are built-in, and most have a string or numeric value.
60 .Uh "Control-flow escapes"
61 A \fIcontrol\fR escape is one of: `%<', `%?', `%|', or `%>'.
62 These are combined into the conditional execution construct:
77 Extra white space is shown here only for clarity. These
78 constructs may be nested without ambiguity. They form a general
79 \fBif\-elseif\-else\-endif\fP block where only one of the \fIformat
80 text\fP segments is interpreted.
82 The `%<' and `%?' control escapes causes a condition to be evaluated.
84 may be either a \fIcomponent\fP or a \fIfunction\fP.
85 The four constructs have the following syntax:
94 These control escapes test whether the function or component value is
95 non-zero (for integer-valued escapes), or non-empty (for string-valued
98 If this test evaulates true, then the format text up to the next
99 corresponding control escape (one of `%|', `%?', or `%>') is interpreted
100 normally. Next, all format text (if any) up to the corresponding `%>'
101 control escape is skipped. The `%>' control escape is not interpreted;
102 normal interpretation resumes after the `%>' escape.
104 If the test evaluates false, however, then the format text up to
105 the next corresponding control escape (again, one of `%|', `%?', or
106 `%>') is skipped, instead of being interpreted. If the control escape
107 encountered was `%?', then the condition associated with that control
108 escape is evaluated, and interpretation proceeds after that test as
109 described in the previous paragraph. If the control escape encountered
110 was `%|', then the format text up to the corresponding `%>' escape is
111 interpreted normally. As above, the `%>' escape is not interpreted and
112 normal interpretation resumes after the `%>' escape.
114 The `%?' control escape and its following format text is optional, and may
115 be included zero or more times. The `%|' control escape and its following
116 format text is also optional, and may be included zero or one times.
118 .Uh "Function escapes"
120 Most functions expect an argument of a particular type:
123 .ta +\w'Argument 'u +\w'An optional component, 'u
124 \fIArgument\fR \fIDescription\fR \fIExample Syntax\fR
125 literal A literal number, %(\fIfunc\fR 1234)
126 or string %(\fIfunc\fR text string)
127 comp Any header component %(\fIfunc\fR\^{\fIin-reply-to\fR\^})
128 date A date component %(\fIfunc\fR\^{\fIdate\fR\^})
129 addr An address component %(\fIfunc\fR\^{\fIfrom\fR\^})
130 expr An optional component, %(\fIfunc\fR\^(\fIfunc2\fR\^))
131 function or control, %(\fIfunc\fR %<{\fIreply-to\fR\^}%|%{\fIfrom\fR\^}%>)
132 perhaps nested %(\fIfunc\fR\^(\fIfunc2\fR\^{\fIcomp\fR\^}))
136 The types \fIdate\fR and \fIaddr\fR have the same syntax as \fIcomp\fR,
137 but require that the header component be a date string, or address
138 string, respectively.
140 All arguments except those of type \fIexpr\fR are required. For the
141 \fIexpr\fR argument type, the leading `%' must be omitted for component
142 and function escape arguments, and must be present (with a leading space)
143 for control escape arguments.
145 The evaluation of format strings is based on a simple virtual machine
146 with an integer register \fInum\fR, and a text string register \fIstr\fR.
147 When a function escape is processed, if it accepts an optional \fIexpr\fR
148 argument which is not present, it reads the current value of either
149 \fInum\fR or \fIstr\fR as appropriate.
152 Component escapes write the value of their message header in \fIstr\fR.
153 Function escapes write their return value in \fInum\fR for functions
154 returning \fIinteger\fR or \fIboolean\fR values, and in \fIstr\fR for
155 functions returning string values. (The \fIboolean\fR type is a subset
156 of integers with usual values 0=false and 1=true.) Control escapes
157 return a \fIboolean\fP value, and set \fInum\fP.
159 All component escapes, and those function escapes which return an
160 \fIinteger\fR or \fIstring\fR value, pass this value back to their caller
161 in addition to setting \fIstr\fR or \fInum\fR. These escapes will print
162 out this value unless called as part of an argument to another escape
163 sequence. Escapes which return a \fIboolean\fR value do pass this value
164 back to their caller in \fInum\fP, but will never print out the value.
167 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
168 \fIFunction\fR \fIArgument\fR \fIReturn\fR \fIDescription\fR
169 msg integer message number
170 cur integer message is current
171 unseen integer message is unseen
172 size integer size of message
173 strlen integer length of \fIstr\fR
174 width integer output buffer size in bytes
175 charleft integer bytes left in output buffer
176 timenow integer seconds since the UNIX epoch
177 me string the user's mailbox
178 eq literal boolean \fInum\fR == \fIarg\fR
179 ne literal boolean \fInum\fR != \fIarg\fR
180 gt literal boolean \fInum\fR > \fIarg\fR
181 match literal boolean \fIstr\fR contains \fIarg\fR
182 amatch literal boolean \fIstr\fR starts with \fIarg\fR
183 plus literal integer \fIarg\fR plus \fInum\fR
184 minus literal integer \fIarg\fR minus \fInum\fR
185 divide literal integer \fInum\fR divided by \fIarg\fR
186 modulo literal integer \fInum\fR modulo \fIarg\fR
187 num literal integer Set \fInum\fR to \fIarg\fR
188 lit literal string Set \fIstr\fR to \fIarg\fR
189 getenv literal string Set \fIstr\fR to environment value of \fIarg\fR
190 profile literal string Set \fIstr\fR to profile component \fIarg\fR value
191 .\" dat literal int return value of dat[arg]
192 nonzero expr boolean \fInum\fR is non-zero
193 zero expr boolean \fInum\fR is zero
194 null expr boolean \fIstr\fR is empty
195 nonnull expr boolean \fIstr\fR is non-empty
196 void expr Set \fIstr\fR or \fInum\fR
197 comp comp string Set \fIstr\fR to component text
198 compval comp integer Set \fInum\fR to \*(lq\fBatoi\fR(\fIcomp\fR\^)\*(rq
199 .\" compflag comp integer Set \fInum\fR to component flags bits (internal)
200 .\" decodecomp comp string Set \fIstr\fR to RFC-2047 decoded component text
201 decode expr string decode \fIstr\fR as RFC-2047 component
202 trim expr trim trailing white-space from \fIstr\fR
203 putstr expr print \fIstr\fR
204 putstrf expr print \fIstr\fR in a fixed width
205 putnum expr print \fInum\fR
206 putnumf expr print \fInum\fR in a fixed width
207 .\" addtoseq literal add msg to sequence (LBL option)
211 These functions require a date component as an argument:
214 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
215 \fIFunction\fR \fIArgument\fR \fIReturn\fR \fIDescription\fR
216 sec date integer seconds of the minute
217 min date integer minutes of the hour
218 hour date integer hours of the day (0-23)
219 wday date integer day of the week (Sun=0)
220 day date string day of the week (abbrev.)
221 weekday date string day of the week
222 sday date integer day of the week known?
223 (0=implicit,\-1=unknown)
224 mday date integer day of the month
225 yday date integer day of the year
226 mon date integer month of the year
227 month date string month of the year (abbrev.)
228 lmonth date string month of the year
229 year date integer year (may be > 100)
230 zone date integer timezone in hours
231 tzone date string timezone string
232 szone date integer timezone explicit?
233 (0=implicit,\-1=unknown)
234 date2local date coerce date to local timezone
235 date2gmt date coerce date to GMT
236 dst date integer daylight savings in effect?
237 clock date integer seconds since the UNIX epoch
238 rclock date integer seconds prior to current time
239 tws date string official 822 rendering
240 pretty date string user-friendly rendering
241 nodate date integer \fIstr\fR not a date string
246 These functions require an address component as an argument.
247 The return value of functions noted with `*' pertain only to
248 the first address present in the header component.
251 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
252 \fIFunction\fR \fIArgument\fR \fIReturn\fR \fIDescription\fR
253 proper addr string official 822 rendering
254 friendly addr string user-friendly rendering
255 addr addr string mbox@host or host!mbox rendering*
256 pers addr string the personal name*
257 note addr string commentary text*
258 mbox addr string the local mailbox*
259 mymbox addr integer the user's addresses? (0=no,1=yes)
260 host addr string the host domain*
261 nohost addr integer no host was present*
262 type addr integer host type* (0=local,1=network,
264 path addr string any leading host route*
265 ingrp addr integer address was inside a group*
266 gname addr string name of group*
267 formataddr expr append \fIarg\fR to \fIstr\fR as a
268 (comma separated) address list
269 putaddr literal print \fIstr\fR address list with
270 \fIarg\fR as optional label;
271 get line width from \fInum\fR
275 When escapes are nested, evaluation is done from inner-most to outer-most.
276 The outer-most escape must begin with `%'; the inner escapes must not.
280 %<(mymbox{from}) To: %{to}%>
282 writes the value of the header component \*(lqFrom:\*(rq to \fIstr\fR\^;
283 then (\fImymbox\fR\^) reads \fIstr\fR and writes its result to \fInum\fR;
284 then the control escape evaluates \fInum\fR. If \fInum\fR is non-zero,
285 the string \*(lqTo: \*(rq is printed followed by the value of the header
286 component \*(lqTo:\*(rq.
288 A minor explanation of (\fImymbox\fR\^{\fIcomp\fR\^}) is in order.
289 In general, it checks each of the addresses in the header component
290 \*(lq\fIcomp\fR\*(rq against the user's mailbox name and any
291 \fIAlternate-Mailboxes\fR. It returns true if any address matches,
292 however, it also returns true if the \*(lq\fIcomp\fR\*(rq header is not
293 present in the message. If needed, the (\fInull\fR\^) function can be
294 used to explicitly test for this condition.
296 When a function or component escape is interpreted and the result will
297 be immediately printed, an optional field width can be specified to
298 print the field in exactly a given number of characters. For example, a
299 numeric escape like %4(\fIsize\fR\^) will print at most 4 digits of the
300 message size; overflow will be indicated by a `?' in the first position
301 (like `?234'). A string escape like %4(\fIme\fR\^) will print the first 4
302 characters and truncate at the end. Short fields are padded at the right
303 with the fill character (normally, a blank). If the field width argument
304 begins with a leading zero, then the fill character is set to a zero.
306 As above, the functions (\fIputnumf\fR\^) and (\fIputstrf\fR\^)
307 print their result in exactly the number of characters
308 specified by their leading field width argument. For example,
309 %06(\fIputnumf\fR\^(\fIsize\fR\^)) will print the message
310 size in a field six characters wide filled with leading zeros;
311 %14(\fIputstrf\^\fR{\fIfrom\^\fR}) will print the \*(lqFrom:\*(rq header
312 component in fourteen characters with trailing spaces added as needed.
313 For \fIputstrf\fR, using a negative value for the field width causes
314 right-justification of the string within the field, with padding on
315 the left up to the field width. The functions (\fIputnum\fR\^) and
316 (\fIputstr\fR\^) print their result in the minimum number of characters
317 required, and ignore any leading field width argument.
319 The available output width is kept in an internal register; any output
320 past this width will be truncated.
322 Comments may be inserted in most places where a function argument is
323 not expected. A comment begins with `%;' and ends with a (non-escaped)
326 With all this in mind,
327 here's the default format string for \fIscan\fR.
328 It's been divided into several pieces for readability.
332 %4(msg)%<(cur)+%| %>%<{replied}\-%?{encrypted}E%| %>
334 which says that the message number should be printed in four digits,
335 if the message is the current message then a `+' else a space should
336 be printed, and if a \*(lqReplied:\*(rq field is present then a `\-'
337 else if an \*(lqEncrypted:\*(rq field is present then an `E' otherwise
338 a space should be printed. Next:
341 %02(mon{date})/%02(mday{date})
343 the month and date are printed in two digits (zero filled) separated by
350 If a \*(lqDate:\*(rq field was present,
351 then a space is printed, otherwise a `*'.
355 %<(mymbox{from})%<{to}To:%14(friendly{to})%>%>
357 if the message is from me,
358 and there is a \*(lqTo:\*(rq header,
359 print `To:' followed by a \*(lquser-friendly\*(rq rendering of the
360 first address in the \*(lqTo:\*(rq field.
364 %<(zero)%17(friendly{from})%>
366 if either of the above two tests failed,
367 then the \*(lqFrom:\*(rq address is printed
368 in a \*(lquser-friendly\*(rq format.
372 %{subject}%<{body}<<%{body}%>
374 the subject and initial body (if any) are printed.
376 For a more complicated example, next consider
377 the default \fIreplcomps\fR format file.
380 %(lit)%(formataddr %<{reply-to}
382 This clears \fIstr\fR and formats the \*(lqReply-To:\*(rq header
383 if present. If not present, the else-if clause is executed.
386 %?{from}%?{sender}%?{return-path}%>)\\
389 \*(lqFrom:\*(rq, \*(lqSender:\*(rq and \*(lqReturn-Path:\*(rq
390 headers, stopping as soon as one of them is present. Next:
393 %<(nonnull)%(void(width))%(putaddr To: )\\n%>\\
395 If the \fIformataddr\fR result is non-null, it is printed as
396 an address (with line folding if needed) in a field \fIwidth\fR
397 wide with a leading label of \*(lqTo: \*(rq.
400 %(lit)%(formataddr{to})%(formataddr{cc})%(formataddr(me))\\
402 \fIstr\fR is cleared, and the
403 \*(lqTo:\*(rq and \*(lqCc:\*(rq headers, along with the user's
405 (depending on what was specified with
406 the \*(lq\-cc\*(rq switch to \fIrepl\fR\^) are formatted.
409 %<(nonnull)%(void(width))%(putaddr cc: )\\n%>\\
411 If the result is non-null, it is printed as above with a
412 leading label of \*(lqcc: \*(rq.
415 %<{fcc}Fcc: %{fcc}\\n%>\\
417 If a \*(lq\-fcc\ folder\*(rq switch was given to \fIrepl\fR
418 (see \fIrepl\fR\0(1) for more details about %{\fIfcc\fR\^}),
419 an \*(lqFcc:\*(rq header is output.
422 %<{subject}Subject: Re: %{subject}\\n%>\\
424 If a subject component was present,
425 a suitable reply subject is output.
429 %<{date}In-reply-to: Your message of "\\
431 %<(nodate{date})%{date}%|%(pretty{date})%>."%<{message-id}
433 %{message-id}%>\\n%>\\
438 If a date component was present, an \*(lqIn-Reply-To:\*(rq header is
439 output with the preface \*(lqYour message of \*(rq. If the date was
440 parseable, it is output in a user-friendly format, otherwise it is
441 output as-is. The message-id is included if present. As with all
442 plain-text, the row of dashes are output as-is.
444 This last part is a good example for a little more elaboration.
445 Here's that part again in pseudo-code:
450 if (comp_exists(date)) then
451 print (\*(lqIn-reply-to: Your message of \\\*(lq\*(rq)
452 if (not_date_string(date.value) then
455 print (pretty(date.value))
457 print (\*(lq\\\*(rq\*(rq)
458 if (comp_exists(message-id)) then
459 print (\*(lq\\n\\t\*(rq)
460 print (message-id.value)
462 print (\*(lq\\n\*(rq)
468 Although this seems complicated,
470 this method is flexible enough to extract individual fields and print them in
471 any format the user desires.
477 scan(1), repl(1), ap(8), dp(8)