comparison doc/mh-format.me @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bce86c4163a3
1 .\" This file is automatically generated. Do not edit!
2 .\" @(#)$Id$
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 /usr/local/mh/lib/scan.time, /usr/local/mh/lib/scan.size, and /usr/local/mh/lib/scan.timely.
23 Look in /usr/local/mh/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