5 .TH MH-FORMAT %manext5% "%nmhdate%" MH.6.8 [%nmhversion%]
7 mh-format \- format file for nmh message system
15 commands utilize either a
19 file during their execution. For example,
21 uses a format string which directs it how to generate the scan listing
24 uses a format file which directs it
25 how to generate the reply to a message, and so on.
27 Format strings are designed to be efficiently parsed by
29 which means they are not necessarily simple to write and understand.
30 This means that novice, casual, or even advanced users of
32 should not have to deal with them.
34 There are a few alternate scan listing formats available
36 .IR %etcdir%/scan.time ,
37 .IR %etcdir%/scan.size ,
39 .IR %etcdir%/scan.timely .
46 format files which may have been written at your site.
48 It suffices to have your local
50 expert actually write new format
51 commands or modify existing ones. This manual section explains how to
52 do that. Note: familiarity with the C
56 A format string consists of ordinary text, and special multi-character
57 escapesequences which begin with `%'. When specifying a format
58 string, the usual C backslash characters are honored: `\\b', `\\f',
59 `\\n', `\\r', and `\\t'. Continuation lines in format files end with
60 `\\' followed by the newline character.
62 .\" TALK ABOUT SYNTAX FIRST, THEN SEMANTICS
64 There are three types of escape sequences: header
73 escape is specified as
76 exists for each header found in the message being processed. For example
78 refers to the \*(lqDate:\*(rq field of the appropriate message.
79 All component escapes have a string value. Normally, component values are
80 compressed by converting any control characters (tab and newline included)
81 to spaces, then eliding any leading or multiple spaces. However, commands
82 may give different interpretations to some component escapes; be sure
83 to refer to each command's manual entry for complete details.
87 escape is specified as
89 All functions are built-in, and most have a string or numeric value.
91 .SS "Control-flow escapes"
94 escape is one of: `%<', `%?', `%|', or `%>'.
95 These are combined into the conditional execution construct:
100 .RI " " "format text 1"
102 .RI " " "format text 2"
104 .RI " " "format text 3"
107 .RI " " "format text N"
112 Extra white space is shown here only for clarity. These
113 constructs may be nested without ambiguity. They form a general
114 .B if\-elseif\-else\-endif
115 block where only one of the
117 segments is interpreted.
119 The `%<' and `%?' control escapes causes a condition to be evaluated.
120 This condition may be either a
124 The four constructs have the following syntax:
135 These control escapes test whether the function or component value is
136 non-zero (for integer-valued escapes), or non-empty (for string-valued
139 If this test evaulates true, then the format text up to the next
140 corresponding control escape (one of `%|', `%?', or `%>') is interpreted
141 normally. Next, all format text (if any) up to the corresponding `%>'
142 control escape is skipped. The `%>' control escape is not interpreted;
143 normal interpretation resumes after the `%>' escape.
145 If the test evaluates false, however, then the format text up to
146 the next corresponding control escape (again, one of `%|', `%?', or
147 `%>') is skipped, instead of being interpreted. If the control escape
148 encountered was `%?', then the condition associated with that control
149 escape is evaluated, and interpretation proceeds after that test as
150 described in the previous paragraph. If the control escape encountered
151 was `%|', then the format text up to the corresponding `%>' escape is
152 interpreted normally. As above, the `%>' escape is not interpreted and
153 normal interpretation resumes after the `%>' escape.
155 The `%?' control escape and its following format text is optional, and may
156 be included zero or more times. The `%|' control escape and its following
157 format text is also optional, and may be included zero or one times.
159 .SS "Function escapes"
160 Most functions expect an argument of a particular type:
164 .ta +\w'Argument 'u +\w'An optional component, 'u
165 .I Argument Description Example Syntax
166 literal A literal number, %(\fIfunc\fR 1234)
167 or string %(\fIfunc\fR text string)
168 comp Any header component %(\fIfunc\fR\^{\fIin-reply-to\fR\^})
169 date A date component %(\fIfunc\fR\^{\fIdate\fR\^})
170 addr An address component %(\fIfunc\fR\^{\fIfrom\fR\^})
171 expr An optional component, %(\fIfunc\fR\^(\fIfunc2\fR\^))
172 function or control, %(\fIfunc\fR %<{\fIreply-to\fR\^}%|%{\fIfrom\fR\^}%>)
173 perhaps nested %(\fIfunc\fR\^(\fIfunc2\fR\^{\fIcomp\fR\^}))
181 have the same syntax as
183 but require that the header component be a date string, or address
184 string, respectively.
186 All arguments except those of type
188 are required. For the
190 argument type, the leading `%' must be omitted for component
191 and function escape arguments, and must be present (with a leading space)
192 for control escape arguments.
194 The evaluation of format strings is based on a simple virtual machine
195 with an integer register
197 , and a text string register
199 When a function escape is processed, if it accepts an optional
201 argument which is not present, it reads the current value of either
208 Component escapes write the value of their message header in
210 Function escapes write their return value in
212 for functions returning integer or boolean values, and in
214 for functions returning string values. (The boolean type is a subset
215 of integers with usual values 0=false and 1=true.) Control escapes
216 return a boolean value, and set
219 All component escapes, and those function escapes which return an
220 integer or string value, pass this value back to their caller
221 in addition to setting
225 These escapes will print
226 out this value unless called as part of an argument to another escape
227 sequence. Escapes which return a boolean value do pass this value
228 back to their caller in
230 but will never print out the value.
234 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
235 .I Function Argument Return Description
236 msg integer message number
237 cur integer message is current
238 unseen integer message is unseen
239 size integer size of message
240 strlen integer length of \fIstr\fR
241 width integer output buffer size in bytes
242 charleft integer bytes left in output buffer
243 timenow integer seconds since the UNIX epoch
244 me string the user's mailbox
245 eq literal boolean \fInum\fR == \fIarg\fR
246 ne literal boolean \fInum\fR != \fIarg\fR
247 gt literal boolean \fInum\fR > \fIarg\fR
248 match literal boolean \fIstr\fR contains \fIarg\fR
249 amatch literal boolean \fIstr\fR starts with \fIarg\fR
250 plus literal integer \fIarg\fR plus \fInum\fR
251 minus literal integer \fIarg\fR minus \fInum\fR
252 divide literal integer \fInum\fR divided by \fIarg\fR
253 modulo literal integer \fInum\fR modulo \fIarg\fR
254 num literal integer Set \fInum\fR to \fIarg\fR
255 lit literal string Set \fIstr\fR to \fIarg\fR
256 getenv literal string Set \fIstr\fR to environment value of \fIarg\fR
257 profile literal string Set \fIstr\fR to profile component \fIarg\fR value
258 .\" dat literal int return value of dat[arg]
259 nonzero expr boolean \fInum\fR is non-zero
260 zero expr boolean \fInum\fR is zero
261 null expr boolean \fIstr\fR is empty
262 nonnull expr boolean \fIstr\fR is non-empty
263 void expr Set \fIstr\fR or \fInum\fR
264 comp comp string Set \fIstr\fR to component text
265 compval comp integer Set \fInum\fR to \*(lq\fBatoi\fR(\fIcomp\fR\^)\*(rq
266 .\" compflag comp integer Set \fInum\fR to component flags bits (internal)
267 .\" decodecomp comp string Set \fIstr\fR to RFC-2047 decoded component text
268 decode expr string decode \fIstr\fR as RFC-2047 component
269 trim expr trim trailing white-space from \fIstr\fR
270 putstr expr print \fIstr\fR
271 putstrf expr print \fIstr\fR in a fixed width
272 putnum expr print \fInum\fR
273 putnumf expr print \fInum\fR in a fixed width
274 .\" addtoseq literal add msg to sequence (LBL option)
278 These functions require a date component as an argument:
282 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
283 .I Function Argument Return Description
284 sec date integer seconds of the minute
285 min date integer minutes of the hour
286 hour date integer hours of the day (0-23)
287 wday date integer day of the week (Sun=0)
288 day date string day of the week (abbrev.)
289 weekday date string day of the week
290 sday date integer day of the week known?
291 (0=implicit,\-1=unknown)
292 mday date integer day of the month
293 yday date integer day of the year
294 mon date integer month of the year
295 month date string month of the year (abbrev.)
296 lmonth date string month of the year
297 year date integer year (may be > 100)
298 zone date integer timezone in hours
299 tzone date string timezone string
300 szone date integer timezone explicit?
301 (0=implicit,\-1=unknown)
302 date2local date coerce date to local timezone
303 date2gmt date coerce date to GMT
304 dst date integer daylight savings in effect?
305 clock date integer seconds since the UNIX epoch
306 rclock date integer seconds prior to current time
307 tws date string official 822 rendering
308 pretty date string user-friendly rendering
309 nodate date integer \fIstr\fR not a date string
313 These functions require an address component as an argument.
314 The return value of functions noted with `*' pertain only to
315 the first address present in the header component.
319 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
320 .I Function Argument Return Description
321 proper addr string official 822 rendering
322 friendly addr string user-friendly rendering
323 addr addr string mbox@host or host!mbox rendering*
324 pers addr string the personal name*
325 note addr string commentary text*
326 mbox addr string the local mailbox*
327 mymbox addr integer the user's addresses? (0=no,1=yes)
328 host addr string the host domain*
329 nohost addr integer no host was present*
330 type addr integer host type* (0=local,1=network,
332 path addr string any leading host route*
333 ingrp addr integer address was inside a group*
334 gname addr string name of group*
335 formataddr expr append \fIarg\fR to \fIstr\fR as a
336 (comma separated) address list
337 putaddr literal print \fIstr\fR address list with
338 \fIarg\fR as optional label;
339 get line width from \fInum\fR
343 When escapes are nested, evaluation is done from inner-most to outer-most.
344 The outer-most escape must begin with `%'; the inner escapes must not.
349 %<(mymbox{from}) To: %{to}%>
353 writes the value of the header component \*(lqFrom:\*(rq to
355 then (\fImymbox\fR\^) reads
357 and writes its result to
359 then the control escape evaluates
363 is non-zero, the string \*(lqTo:\*(rq is printed followed by the value of the header
364 component \*(lqTo:\*(rq.
366 A minor explanation of (\fImymbox\fR\^{\fIcomp\fR\^}) is in order.
367 In general, it checks each of the addresses in the header component
368 \*(lq\fIcomp\fR\*(rq against the user's mailbox name and any
369 .RI \*(lq Alternate-Mailboxes \*(rq.
370 It returns true if any address matches,
371 however, it also returns true if the \*(lq\fIcomp\fR\*(rq header is not
372 present in the message. If needed, the (\fInull\fR\^) function can be
373 used to explicitly test for this condition.
375 When a function or component escape is interpreted and the result will
376 be immediately printed, an optional field width can be specified to
377 print the field in exactly a given number of characters. For example, a
378 numeric escape like %4(\fIsize\fR\^) will print at most 4 digits of the
379 message size; overflow will be indicated by a `?' in the first position
380 (like `?234'). A string escape like %4(\fIme\fR\^) will print the first 4
381 characters and truncate at the end. Short fields are padded at the right
382 with the fill character (normally, a blank). If the field width argument
383 begins with a leading zero, then the fill character is set to a zero.
385 As above, the functions (\fIputnumf\fR\^) and (\fIputstrf\fR\^)
386 print their result in exactly the number of characters
387 specified by their leading field width argument. For example,
388 %06(\fIputnumf\fR\^(\fIsize\fR\^)) will print the message
389 size in a field six characters wide filled with leading zeros;
390 %14(\fIputstrf\^\fR{\fIfrom\^\fR}) will print the \*(lqFrom:\*(rq header
391 component in fourteen characters with trailing spaces added as needed.
392 For \fIputstrf\fR, using a negative value for the field width causes
393 right-justification of the string within the field, with padding on
394 the left up to the field width. The functions (\fIputnum\fR\^) and
395 (\fIputstr\fR\^) print their result in the minimum number of characters
396 required, and ignore any leading field width argument.
398 The available output width is kept in an internal register; any output
399 past this width will be truncated.
401 Comments may be inserted in most places where a function argument is
402 not expected. A comment begins with `%;' and ends with a (non-escaped)
405 With all this in mind,
406 here's the default format string for
408 It's been divided into several pieces for readability.
413 %4(msg)%<(cur)+%| %>%<{replied}\-%?{encrypted}E%| %>
417 which says that the message number should be printed in four digits,
418 if the message is the current message then a `+' else a space should
419 be printed, and if a \*(lqReplied:\*(rq field is present then a `\-'
420 else if an \*(lqEncrypted:\*(rq field is present then an `E' otherwise
421 a space should be printed. Next:
425 %02(mon{date})/%02(mday{date})
429 the month and date are printed in two digits (zero filled) separated by
438 If a \*(lqDate:\*(rq field was present,
439 then a space is printed, otherwise a `*'.
444 %<(mymbox{from})%<{to}To:%14(friendly{to})%>%>
448 if the message is from me,
449 and there is a \*(lqTo:\*(rq header,
450 print `To:' followed by a \*(lquser-friendly\*(rq rendering of the
451 first address in the \*(lqTo:\*(rq field.
456 %<(zero)%17(friendly{from})%>
460 if either of the above two tests failed,
461 then the \*(lqFrom:\*(rq address is printed
462 in a \*(lquser-friendly\*(rq format.
467 %{subject}%<{body}<<%{body}%>
471 the subject and initial body (if any) are printed.
473 For a more complicated example, next consider
480 %(lit)%(formataddr %<{reply-to}
486 and formats the \*(lqReply-To:\*(rq header
487 if present. If not present, the else-if clause is executed.
491 %?{from}%?{sender}%?{return-path}%>)\\
496 \*(lqFrom:\*(rq, \*(lqSender:\*(rq and \*(lqReturn-Path:\*(rq
497 headers, stopping as soon as one of them is present. Next:
501 %<(nonnull)%(void(width))%(putaddr To: )\\n%>\\
505 If the \fIformataddr\fR result is non-null, it is printed as
506 an address (with line folding if needed) in a field \fIwidth\fR
507 wide with a leading label of \*(lqTo:\*(rq.
511 %(lit)%(formataddr{to})%(formataddr{cc})%(formataddr(me))\\
516 is cleared, and the \*(lqTo:\*(rq and \*(lqCc:\*(rq headers, along with the user's
517 address (depending on what was specified with
518 the \*(lq\-cc\*(rq switch to \fIrepl\fR\^) are formatted.
522 %<(nonnull)%(void(width))%(putaddr cc: )\\n%>\\
526 If the result is non-null, it is printed as above with a
527 leading label of \*(lqcc:\*(rq.
531 %<{fcc}Fcc: %{fcc}\\n%>\\
542 for more details about %{\fIfcc\fR\^}),
543 an \*(lqFcc:\*(rq header is output.
547 %<{subject}Subject: Re: %{subject}\\n%>\\
551 If a subject component was present,
552 a suitable reply subject is output.
556 %<{date}In-reply-to: Your message of "\\
557 %<(nodate{date})%{date}%|%(pretty{date})%>."%<{message-id}
558 %{message-id}%>\\n%>\\
563 If a date component was present, an \*(lqIn-Reply-To:\*(rq header is
564 output with the preface \*(lqYour message of \*(rq. If the date was
565 parseable, it is output in a user-friendly format, otherwise it is
566 output as-is. The message-id is included if present. As with all
567 plain-text, the row of dashes are output as-is.
569 This last part is a good example for a little more elaboration.
570 Here's that part again in pseudo-code:
575 if (comp_exists(date)) then
576 print (\*(lqIn-reply-to: Your message of \\\*(lq\*(rq)
577 if (not_date_string(date.value) then
580 print (pretty(date.value))
582 print (\*(lq\\\*(rq\*(rq)
583 if (comp_exists(message-id)) then
584 print (\*(lq\\n\\t\*(rq)
585 print (message-id.value)
587 print (\*(lq\\n\*(rq)
592 Although this seems complicated,
594 this method is flexible enough to extract individual fields and print them in
595 any format the user desires.
598 scan(1), repl(1), ap(8), dp(8)