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 $
5 mh-format \- format file for MH message system
9 Several \fIMH\fR commands utilize either a \fIformat\fR string or a
10 \fIformat\fR file during their execution.
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.
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.
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.
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:
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.
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
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.
53 commands may give different interpretations to some component escapes;
54 be sure 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 `%>'.
63 These are combined into the conditional execution construct:
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.
83 The `%<' and `%?' control escapes causes a condition to be evaluated.
85 may be either a \fIcomponent\fP or a \fIfunction\fP.
86 The four constructs have the following syntax:
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).
99 If this test evaulates true,
101 up to the next corresponding control escape
102 (one of `%|', `%?', or `%>')
103 is interpreted normally.
105 all format text (if any) up to the corresponding `%>' control
107 The `%>' control escape is not interpreted;
109 interpretation resumes after the `%>' escape.
111 If the test evaluates false, however,
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 `%|',
123 up to the corresponding `%>' escape
124 is interpreted normally.
126 the `%>' escape is not interpreted and normal
127 interpretation resumes after the `%>' escape.
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.
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).
143 .Uh "Function escapes"
145 Most functions expect an argument of a particular type:
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\^}))
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.
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.
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.
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.
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.
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)
239 These functions require a date component as an argument:
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
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.
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,
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
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.
308 %<(mymbox{from}) To: %{to}%>
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.
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
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.
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
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.
340 the functions (\fIputnumf\fR\^) and (\fIputstrf\fR\^) print their result in
341 exactly the number of characters specified by their leading field width
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.
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.
357 The available output width is kept in an internal register; any output past
358 this width will be truncated.
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.
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.
370 %4(msg)%<(cur)+%| %>%<{replied}\-%?{encrypted}E%| %>
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
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.
381 %02(mon{date})/%02(mday{date})
383 the month and date are printed in two digits (zero filled) separated by
390 If a \*(lqDate:\*(rq field was present,
391 then a space is printed, otherwise a `*'.
395 %<(mymbox{from})%<{to}To:%14(friendly{to})%>%>
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.
404 %<(zero)%17(friendly{from})%>
406 if either of the above two tests failed,
407 then the \*(lqFrom:\*(rq address is printed
408 in a \*(lquser-friendly\*(rq format.
412 %{subject}%<{body}<<%{body}%>
414 the subject and initial body (if any) are printed.
416 For a more complicated example, next consider
417 the default \fIreplcomps\fR format file.
420 %(lit)%(formataddr %<{reply-to}
422 This clears \fIstr\fR and formats the \*(lqReply-To:\*(rq header
423 if present. If not present, the else-if clause is executed.
426 %?{from}%?{sender}%?{return-path}%>)\\
429 \*(lqFrom:\*(rq, \*(lqSender:\*(rq and \*(lqReturn-Path:\*(rq
430 headers, stopping as soon as one of them is present. Next:
433 %<(nonnull)%(void(width))%(putaddr To: )\\n%>\\
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.
440 %(lit)%(formataddr{to})%(formataddr{cc})%(formataddr(me))\\
442 \fIstr\fR is cleared, and the
443 \*(lqTo:\*(rq and \*(lqCc:\*(rq headers, along with the user's
445 (depending on what was specified with
446 the \*(lq\-cc\*(rq switch to \fIrepl\fR\^) are formatted.
449 %<(nonnull)%(void(width))%(putaddr cc: )\\n%>\\
451 If the result is non-null, it is printed as above with a
452 leading label of \*(lqcc: \*(rq.
455 %<{fcc}Fcc: %{fcc}\\n%>\\
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.
462 %<{subject}Subject: Re: %{subject}\\n%>\\
464 If a subject component was present,
465 a suitable reply subject is output.
469 %<{date}In-reply-to: Your message of "\\
471 %<(nodate{date})%{date}%|%(pretty{date})%>."%<{message-id}
473 %{message-id}%>\\n%>\\
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.
486 This last part is a good example for a little more elaboration.
487 Here's that part again in pseudo-code:
492 if (comp_exists(date)) then
493 print (\*(lqIn-reply-to: Your message of \\\*(lq\*(rq)
494 if (not_date_string(date.value) then
497 print (pretty(date.value))
499 print (\*(lq\\\*(rq\*(rq)
500 if (comp_exists(message-id)) then
501 print (\*(lq\\n\\t\*(rq)
502 print (message-id.value)
504 print (\*(lq\\n\*(rq)
510 Although this seems complicated,
512 this method is flexible enough to extract individual fields and print them in
513 any format the user desires.
519 scan(1), repl(1), ap(8), dp(8)
525 This software was contributed for MH 6.3. Prior to this, output
526 format specifications were much easier to write, but considerably
529 On hosts where \fIMH\fR was configured with the BERK option,
530 address parsing is not enabled.