Added test of -nosequence to test-pick.
[mmh] / docs / historical / mh-6.8.5 / doc / mh-format.me
1 .\"     This file is automatically generated.  Do not edit!
2 .\" @(#)$Id: mh-format.rf,v 1.47 1995/12/06 23:33:39 jromine Exp $
3 .SC MH-FORMAT 5
4 .NA
5 mh-format \- format file for MH message system
6 .SY
7 some \fIMH\fR commands
8 .DE
9 Several \fIMH\fR commands utilize either a \fIformat\fR string or a
10 \fIformat\fR file during their execution.
11 For example,
12 \fIscan\fR\0(1) uses a format string which directs it how to generate the
13 scan listing for each message;
14 \fIrepl\fR\0(1) uses a format file which directs it how to generate the
15 reply to a message, and so on.
16
17 Format strings are designed to be efficiently parsed by \fIMH\fR which
18 means they are not necessarily simple to write and understand.
19 This means that novice, casual, or even advanced users of \fIMH\fR should
20 not have to deal with them.
21 Some canned scan listing formats are in
22 /opt/mh-6.8.5/lib/scan.time, /opt/mh-6.8.5/lib/scan.size, and /opt/mh-6.8.5/lib/scan.timely.
23 Look in /opt/mh-6.8.5/lib for other \fIscan\fR and \fIrepl\fR format files
24 which may have been written at your site.
25
26 It suffices to have your local \fIMH\fR expert actually write new format
27 commands or modify existing ones.
28 This manual section explains how to do that.
29 Note: familiarity with the C \fIprintf\fR routine is assumed.
30
31 A format string consists of ordinary text, and special
32 multi-character \fIescape\fR sequences which begin with `%'.
33 When specifying a format string,
34 the usual C backslash characters are honored:
35 `\\b', `\\f', `\\n', `\\r', and `\\t'.
36 Continuation lines in format files end with `\\' followed
37 by the newline character.
38 To put a literal `%' or `\\' in a format string, use two of them:
39 `%%' and `\\\\'.
40 .\" talk about syntax first, then semantics
41 There are three types of \fIescape\fR sequences:
42 header \fIcomponents\fR, built-in \fIfunctions\fR, and flow \fIcontrol\fR.
43
44 A \fIcomponent\fR escape is specified as `%{\fIcomponent\fR\^}',
45 and exists for each header found in the message being processed.
46 For example `%{date}' refers to the \*(lqDate:\*(rq field of the appropriate
47 message.
48 All component escapes have a string value.
49 Normally, component values are compressed by
50 converting any control characters (tab and newline included) to spaces,
51 then eliding any leading or multiple spaces.
52 However,
53 commands may give different interpretations to some component escapes; 
54 be sure to refer to each command's manual entry for complete details.
55
56 A \fIfunction\fR escape is specified as `%(\fIfunction\fR\^)'.
57 All functions are built-in, and most have a string or numeric value.
58
59 .ne 12
60 .Uh "Control-flow escapes"
61 A \fIcontrol\fR escape is one of: `%<', `%?', `%|', or `%>'. 
62 .\" `%[', or `%]'.
63 These are combined into the conditional execution construct:
64 .sp
65 .nf
66         %<condition
67                 \fIformat text 1\fP
68         %?condition2
69                 \fIformat text 2\fP
70         %?condition3
71                 \fIformat text 3\fP
72         \.\.\.
73         %|
74                 \fIformat text N\fP
75         %>
76 .fi
77 .sp
78 Extra white space is shown here only for clarity.
79 These constructs may be nested without ambiguity.
80 They form a general \fBif\-elseif\-else\-endif\fP block where
81 only one of the \fIformat text\fP segments is interpreted.
82
83 The `%<' and `%?' control escapes causes a condition to be evaluated.  
84 This condition
85 may be either a \fIcomponent\fP or a \fIfunction\fP.
86 The four constructs have the following syntax:
87 .sp 1
88 .nf
89         %<{component}
90         %<(function)
91         %?{component}
92         %?(function)
93 .fi
94 .sp
95 These control escapes test whether
96 the function or component value is non-zero (for integer-valued escapes),
97 or non-empty (for string-valued escapes).
98
99 If this test evaulates true,
100 then the format text
101 up to the next corresponding control escape 
102 (one of `%|', `%?', or `%>')
103 is interpreted normally.
104 Next,
105 all format text (if any) up to the corresponding `%>' control
106 escape is skipped.
107 The `%>' control escape is not interpreted;
108 normal
109 interpretation resumes after the `%>' escape.
110
111 If the test evaluates false, however,
112 then the format text 
113 up to the next corresponding control escape
114 (again, one of `%|', `%?', or `%>')
115 is skipped, instead of being interpreted.
116 If the control escape encountered was `%?',
117 then the condition associated with that control escape is
118 evaluated, and interpretation
119 proceeds after that test
120 as described in the previous paragraph.
121 If the control escape encountered was `%|',
122 then the format text
123 up to the corresponding `%>' escape
124 is interpreted normally.
125 As above, 
126 the `%>' escape is not interpreted and normal
127 interpretation resumes after the `%>' escape.
128
129 The `%?' control escape and its following format text
130 is optional, and may be included zero or more times.
131 The `%|' control escape and its following format text
132 is also optional, and may be included zero or one times.
133
134 .\" The '%[' and '%]' escapes form a loop construct.
135 .\" For format strings which are executed repeatedly
136 .\" (as with \fIscan\fP), these escapes delimit the main
137 .\" body of execution.  Format text which occurs
138 .\" before the '%[' escape is executed once only, prior
139 .\" to processing the first message; format text occuring
140 .\" after the '%]' escape is ignored.
141 .\" (These escapes may not be nested).
142 .\" 
143 .Uh "Function escapes"
144 .ne 10
145 Most functions expect an argument of a particular type:
146 .sp 1
147 .nf
148 .ta +\w'Argument 'u +\w'An optional component, 'u
149 \fIArgument\fR  \fIDescription\fR       \fIExample Syntax\fR
150 literal A literal number,       %(\fIfunc\fR 1234)
151         or string       %(\fIfunc\fR text string)
152 comp    Any header component    %(\fIfunc\fR\^{\fIin-reply-to\fR\^})
153 date    A date component        %(\fIfunc\fR\^{\fIdate\fR\^})
154 addr    An address component    %(\fIfunc\fR\^{\fIfrom\fR\^})
155 expr    An optional component,  %(\fIfunc\fR\^(\fIfunc2\fR\^))
156         function or control,    %(\fIfunc\fR %<{\fIreply-to\fR\^}%|%{\fIfrom\fR\^}%>)
157         perhaps nested  %(\fIfunc\fR\^(\fIfunc2\fR\^{\fIcomp\fR\^}))
158 .re
159 .fi
160
161 The types \fIdate\fR and \fIaddr\fR have the same syntax
162 as \fIcomp\fR, but require that the header 
163 component be a date string, or address string, respectively.
164
165 All arguments except those of type \fIexpr\fR are required.
166 For the \fIexpr\fR argument type, 
167 the leading `%' must be omitted for component and function escape arguments,
168 and must be present (with a leading space) for control escape arguments.
169
170 The evaluation of format strings
171 is based on a simple machine with an
172 integer register \fInum\fR, and a text string register \fIstr\fR.
173 When a function escape is processed,
174 if it accepts an optional \fIexpr\fR argument which is not present, 
175 it reads the current value of either \fInum\fR or \fIstr\fR as appropriate.
176
177 .\" return values
178 .Uh "Return values"
179 Component escapes write the value of their message header in \fIstr\fR.
180 Function escapes write their return value in
181 \fInum\fR for functions returning \fIinteger\fR or \fIboolean\fR values,
182 and in \fIstr\fR for functions returning string values.
183 (The \fIboolean\fR type is a subset of integers with usual
184 values 0=false and 1=true.)
185 Control escapes return a \fIboolean\fP value, and set \fInum\fP.
186
187 All component escapes, and those
188 function escapes which return an \fIinteger\fR or \fIstring\fR value,
189 pass this value back to their caller
190 in addition to setting \fIstr\fR or \fInum\fR.
191 These escapes will print out this value
192 unless called as part of an argument to another escape sequence.
193 Escapes which return a \fIboolean\fR value do pass this value
194 back to their caller in \fInum\fP, but will never print out the value.
195
196 .nf
197 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
198 \fIFunction\fR  \fIArgument\fR  \fIReturn\fR    \fIDescription\fR
199 msg             integer message number
200 cur             integer message is current
201 .\" unseen              integer message is unseen
202 size            integer size of message
203 strlen          integer length of \fIstr\fR
204 width           integer output buffer size in bytes
205 charleft                integer bytes left in output buffer
206 timenow         integer seconds since the UNIX epoch
207 me              string  the user's mailbox
208 eq      literal boolean \fInum\fR == \fIarg\fR
209 ne      literal boolean \fInum\fR != \fIarg\fR
210 gt      literal boolean \fInum\fR > \fIarg\fR
211 match   literal boolean \fIstr\fR contains \fIarg\fR
212 amatch  literal boolean \fIstr\fR starts with \fIarg\fR
213 plus    literal integer \fIarg\fR plus \fInum\fR
214 minus   literal integer \fIarg\fR minus \fInum\fR
215 divide  literal integer \fInum\fR divided by \fIarg\fR
216 modulo  literal integer \fInum\fR modulo \fIarg\fR
217 num     literal integer Set \fInum\fR to \fIarg\fR
218 lit     literal string  Set \fIstr\fR to \fIarg\fR
219 getenv  literal string  Set \fIstr\fR to environment value of \fIarg\fR
220 profile literal string  Set \fIstr\fR to profile component \fIarg\fR value
221 .\" dat literal int     return value of dat[arg]
222 nonzero expr    boolean \fInum\fR is non-zero
223 zero    expr    boolean \fInum\fR is zero
224 null    expr    boolean \fIstr\fR is empty
225 nonnull expr    boolean \fIstr\fR is non-empty
226 void    expr            Set \fIstr\fR or \fInum\fR
227 comp    comp    string  Set \fIstr\fR to component text
228 compval comp    integer \fInum\fR set to \*(lq\fBatoi\fR(\fIcomp\fR\^)\*(rq
229 .\" compflag    comp    integer Set \fInum\fR to component flags bits (internal)
230 trim    expr            trim trailing white-space from \fIstr\fR
231 putstr  expr            print \fIstr\fR
232 putstrf expr            print \fIstr\fR in a fixed width
233 putnum  expr            print \fInum\fR
234 putnumf expr            print \fInum\fR in a fixed width
235 .\" addtoseq literal    add msg to sequence (LBL option)
236 .re     
237 .fi
238
239 These functions require a date component as an argument:
240 .sp 1
241 .nf
242 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
243 \fIFunction\fR  \fIArgument\fR  \fIReturn\fR    \fIDescription\fR
244 sec     date    integer seconds of the minute
245 min     date    integer minutes of the hour
246 hour    date    integer hours of the day (0-23)
247 wday    date    integer day of the week (Sun=0)
248 day     date    string  day of the week (abbrev.)
249 weekday date    string  day of the week
250 sday    date    integer day of the week known?
251                         (0=implicit,\-1=unknown)
252 mday    date    integer day of the month
253 yday    date    integer day of the year
254 mon     date    integer month of the year
255 month   date    string  month of the year (abbrev.)
256 lmonth  date    string  month of the year
257 year    date    integer year (may be > 100)
258 zone    date    integer timezone in hours
259 tzone   date    string  timezone string
260 szone   date    integer timezone explicit?
261                         (0=implicit,\-1=unknown)
262 date2local      date            coerce date to local timezone
263 date2gmt        date            coerce date to GMT
264 dst     date    integer daylight savings in effect?
265 clock   date    integer seconds since the UNIX epoch
266 rclock  date    integer seconds prior to current time
267 tws     date    string  official 822 rendering
268 pretty  date    string  user-friendly rendering
269 nodate  date    integer \fIstr\fR not a date string
270 .re     
271 .fi
272
273 .ne 12
274 These functions require an address component as an argument.  
275 The return value of functions noted with `*' pertain only to
276 the first address present in the header component.
277 .sp 1
278 .nf
279 .ta \w'Formataddr 'u +\w'Argument 'u +\w'Rboolean 'u
280 \fIFunction\fR  \fIArgument\fR  \fIReturn\fR    \fIDescription\fR
281 proper  addr    string  official 822 rendering
282 friendly        addr    string  user-friendly rendering
283 addr    addr    string  mbox@host or host!mbox rendering*
284 pers    addr    string  the personal name*
285 note    addr    string  commentary text*
286 mbox    addr    string  the local mailbox*
287 mymbox  addr    integer the user's addresses? (0=no,1=yes)
288 host    addr    string  the host domain*
289 nohost  addr    integer no host was present*
290 type    addr    integer host type* (0=local,1=network,
291                         \-1=uucp,2=unknown)
292 path    addr    string  any leading host route*
293 ingrp   addr    integer address was inside a group*
294 gname   addr    string  name of group*
295 formataddr      expr            append \fIarg\fR to \fIstr\fR as a
296                         (comma separated) address list
297 putaddr literal         print \fIstr\fR address list with
298                         \fIarg\fR as optional label;
299                         get line width from \fInum\fR
300 .re     
301 .fi
302
303 When escapes are nested, evaluation is done from inner-most to outer-most.
304 The outer-most escape must begin with `%'; the inner escapes must not.
305 For example,
306
307 .ti +.5i
308 %<(mymbox{from}) To: %{to}%>
309
310 writes the value of the header component \*(lqFrom:\*(rq to \fIstr\fR\^;
311 then (\fImymbox\fR\^) reads \fIstr\fR 
312 and writes its result to \fInum\fR;
313 then the control escape evaluates \fInum\fR.  If \fInum\fR is
314 non-zero, the string \*(lqTo: \*(rq is printed followed by
315 the value of the header component \*(lqTo:\*(rq.
316
317 A minor explanation of (\fImymbox\fR\^{\fIcomp\fR\^}) is in order.
318 In general, it checks each of the addresses in the header component
319 \*(lq\fIcomp\fR\*(rq
320 against the user's mailbox name and any \fIAlternate-Mailboxes\fR.
321 It returns true if any address matches, however, it
322 also returns true if the \*(lq\fIcomp\fR\*(rq header is not present
323 in the message.  If needed, the (\fInull\fR\^) function can be
324 used to explicitly test for this condition.
325
326 When a function or component escape is interpreted and the result
327 will be immediately printed,
328 an optional field width can be
329 specified to print the field in exactly a given number of characters.
330 For example, a numeric escape like %4(\fIsize\fR\^) will print at most 4
331 digits of the message size; overflow will be indicated by a `?' in the
332 first position (like `?234').
333 A string escape like %4(\fIme\fR\^) will print the first 4 characters and
334 truncate at the end.  
335 Short fields are padded at the right with the fill character (normally,
336 a blank).  If the field width argument begins with a leading zero,
337 then the fill character is set to a zero.
338
339 As above,
340 the functions (\fIputnumf\fR\^) and (\fIputstrf\fR\^) print their result in
341 exactly the number of characters specified by their leading field width
342 argument.  
343 For example,
344 %06(\fIputnumf\fR\^(\fIsize\fR\^)) will print the message size 
345 in a field six characters wide filled with leading zeros;
346 %14(\fIputstrf\^\fR{\fIfrom\^\fR}) will print
347 the \*(lqFrom:\*(rq header component in fourteen characters with
348 trailing spaces added as needed.
349 For \fIputstrf\fR,
350 using a negative value for the field width causes right-justification
351 of the string within the field,
352 with padding on the left up to the field width.
353 The functions (\fIputnum\fR\^) and (\fIputstr\fR\^) print their result in
354 the minimum number of characters required, and ignore any leading 
355 field width argument.
356
357 The available output width is kept in an internal register; any output past
358 this width will be truncated.
359
360 Comments may be inserted in most places where a function argument
361 is not expected.  A comment begins with `%;' and ends with
362 a (non-escaped) newline.
363
364 With all this in mind,
365 here's the default format string for \fIscan\fR.
366 It's been divided into several pieces for readability.
367 The first part is:
368
369 .ti +.5i
370 %4(msg)%<(cur)+%| %>%<{replied}\-%?{encrypted}E%| %>
371
372 which says that the message number should be printed in four digits,
373 if the message is the current message then a `+' else a space should be
374 printed,
375 and if a \*(lqReplied:\*(rq field is present then a `\-' else 
376 if an \*(lqEncrypted:\*(rq field is present then an `E' otherwise
377 a space should be printed.
378 Next:
379
380 .ti +.5i
381 %02(mon{date})/%02(mday{date})
382
383 the month and date are printed in two digits (zero filled) separated by
384 a slash.
385 Next,
386
387 .ti +.5i
388 %<{date} %|*>
389
390 If a \*(lqDate:\*(rq field was present,
391 then a space is printed, otherwise a `*'.
392 Next,
393
394 .ti +.5i
395 %<(mymbox{from})%<{to}To:%14(friendly{to})%>%>
396
397 if the message is from me,
398 and there is a \*(lqTo:\*(rq header,
399 print `To:' followed by a \*(lquser-friendly\*(rq rendering of the 
400 first address in the \*(lqTo:\*(rq field.
401 Continuing,
402
403 .ti +.5i
404 %<(zero)%17(friendly{from})%>
405
406 if either of the above two tests failed,
407 then the \*(lqFrom:\*(rq address is printed
408 in a \*(lquser-friendly\*(rq format.
409 And finally,
410
411 .ti +.5i
412 %{subject}%<{body}<<%{body}%>
413
414 the subject and initial body (if any) are printed.
415
416 For a more complicated example, next consider
417 the default \fIreplcomps\fR format file.
418
419 .ti +.5i
420 %(lit)%(formataddr %<{reply-to}
421
422 This clears \fIstr\fR and formats the \*(lqReply-To:\*(rq header 
423 if present.  If not present, the else-if clause is executed.
424
425 .ti +.5i
426 %?{from}%?{sender}%?{return-path}%>)\\
427
428 This formats the 
429 \*(lqFrom:\*(rq, \*(lqSender:\*(rq and \*(lqReturn-Path:\*(rq
430 headers, stopping as soon as one of them is present.  Next:
431
432 .ti +.5i
433 %<(nonnull)%(void(width))%(putaddr To: )\\n%>\\
434
435 If the \fIformataddr\fR result is non-null, it is printed as
436 an address (with line folding if needed) in a field \fIwidth\fR
437 wide with a leading label of \*(lqTo: \*(rq.
438
439 .ti +.5i
440 %(lit)%(formataddr{to})%(formataddr{cc})%(formataddr(me))\\
441
442 \fIstr\fR is cleared, and the 
443 \*(lqTo:\*(rq and \*(lqCc:\*(rq headers, along with the user's
444 address 
445 (depending on what was specified with
446 the \*(lq\-cc\*(rq switch to \fIrepl\fR\^) are formatted.
447
448 .ti +.5i
449 %<(nonnull)%(void(width))%(putaddr cc: )\\n%>\\
450
451 If the result is non-null, it is printed as above with a
452 leading label of \*(lqcc: \*(rq.
453
454 .ti +.5i
455 %<{fcc}Fcc: %{fcc}\\n%>\\
456
457 If a \*(lq\-fcc\ folder\*(rq switch was given to \fIrepl\fR
458 (see \fIrepl\fR\0(1) for more details about %{\fIfcc\fR\^}),
459 an \*(lqFcc:\*(rq header is output.
460
461 .ti +.5i
462 %<{subject}Subject: Re: %{subject}\\n%>\\
463
464 If a subject component was present,
465 a suitable reply subject is output.
466
467 .nf
468 .ti +.5i
469 %<{date}In-reply-to: Your message of "\\
470 .ti +.5i
471 %<(nodate{date})%{date}%|%(pretty{date})%>."%<{message-id}
472 .ti +.5i
473              %{message-id}%>\\n%>\\
474 .ti +.5i
475 \-\-\-\-\-\-\-\-
476 .fi
477
478 If a date component was present,
479 an \*(lqIn-Reply-To:\*(rq header is output with the preface
480 \*(lqYour message of \*(rq.  If the date was parseable, it is
481 output in a user-friendly format, otherwise it is output as-is.
482 The message-id is included if present.
483 As with all plain-text,
484 the row of dashes are output as-is.
485
486 This last part is a good example for a little more elaboration.
487 Here's that part again in pseudo-code:
488 .sp 1
489 .nf
490 .in +.5i
491 .ta .5i 1i 1.5i 2i
492 if (comp_exists(date))  then
493         print (\*(lqIn-reply-to: Your message of \\\*(lq\*(rq)
494         if (not_date_string(date.value) then
495                 print (date.value)
496         else
497                 print (pretty(date.value))
498         endif
499         print (\*(lq\\\*(rq\*(rq)
500         if (comp_exists(message-id)) then
501                 print (\*(lq\\n\\t\*(rq)
502                 print (message-id.value)
503         endif
504         print (\*(lq\\n\*(rq)
505 endif
506 .re
507 .in -.5i
508 .fi
509 .sp 1
510 Although this seems complicated,
511 in point of fact,
512 this method is flexible enough to extract individual fields and print them in
513 any format the user desires.
514 .Fi
515 None
516 .Pr
517 None
518 .Sa
519 scan(1), repl(1), ap(8), dp(8)
520 .De
521 None
522 .Co
523 None
524 .Hi
525 This software was contributed for MH 6.3.  Prior to this, output
526 format specifications were much easier to write, but considerably
527 less flexible.
528 .Bu
529 On hosts where \fIMH\fR was configured with the BERK option,
530 address parsing is not enabled.
531 .En