1 | .\" |
---|
2 | .\" %nmhwarning% |
---|
3 | .\" $Id: mh-format.man,v 1.1.1.1 1999-02-07 18:14:20 danw Exp $ |
---|
4 | .\" |
---|
5 | .\" include the -mh macro file |
---|
6 | .so %etcdir%/tmac.h |
---|
7 | .\" |
---|
8 | .TH MH-FORMAT %manext5% MH.6.8 [%nmhversion%] |
---|
9 | .SH NAME |
---|
10 | mh-format \- format file for nmh message system |
---|
11 | .SH SYNOPSIS |
---|
12 | .in +.5i |
---|
13 | .ti -.5i |
---|
14 | some \fInmh\fR commands |
---|
15 | .in -.5i |
---|
16 | .SH DESCRIPTION |
---|
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. |
---|
22 | |
---|
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. |
---|
27 | |
---|
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. |
---|
32 | |
---|
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. |
---|
36 | |
---|
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. |
---|
42 | |
---|
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. |
---|
46 | |
---|
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. |
---|
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 | These are combined into the conditional execution construct: |
---|
63 | .sp |
---|
64 | .nf |
---|
65 | %<condition |
---|
66 | \fIformat text 1\fP |
---|
67 | %?condition2 |
---|
68 | \fIformat text 2\fP |
---|
69 | %?condition3 |
---|
70 | \fIformat text 3\fP |
---|
71 | \.\.\. |
---|
72 | %| |
---|
73 | \fIformat text N\fP |
---|
74 | %> |
---|
75 | .fi |
---|
76 | .sp |
---|
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. |
---|
81 | |
---|
82 | The `%<' and `%?' control escapes causes a condition to be evaluated. |
---|
83 | This condition |
---|
84 | may be either a \fIcomponent\fP or a \fIfunction\fP. |
---|
85 | The four constructs have the following syntax: |
---|
86 | .sp 1 |
---|
87 | .nf |
---|
88 | %<{component} |
---|
89 | %<(function) |
---|
90 | %?{component} |
---|
91 | %?(function) |
---|
92 | .fi |
---|
93 | .sp |
---|
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 |
---|
96 | escapes). |
---|
97 | |
---|
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. |
---|
103 | |
---|
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. |
---|
113 | |
---|
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. |
---|
117 | |
---|
118 | .Uh "Function escapes" |
---|
119 | .ne 10 |
---|
120 | Most functions expect an argument of a particular type: |
---|
121 | .sp 1 |
---|
122 | .nf |
---|
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\^})) |
---|
133 | .re |
---|
134 | .fi |
---|
135 | |
---|
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. |
---|
139 | |
---|
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. |
---|
144 | |
---|
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. |
---|
150 | |
---|
151 | .Uh "Return values" |
---|
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. |
---|
158 | |
---|
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. |
---|
165 | |
---|
166 | .nf |
---|
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) |
---|
208 | .re |
---|
209 | .fi |
---|
210 | |
---|
211 | These functions require a date component as an argument: |
---|
212 | .sp 1 |
---|
213 | .nf |
---|
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 |
---|
242 | .re |
---|
243 | .fi |
---|
244 | |
---|
245 | .ne 12 |
---|
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. |
---|
249 | .sp 1 |
---|
250 | .nf |
---|
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, |
---|
263 | \-1=uucp,2=unknown) |
---|
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 |
---|
272 | .re |
---|
273 | .fi |
---|
274 | |
---|
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. |
---|
277 | For example, |
---|
278 | |
---|
279 | .ti +.5i |
---|
280 | %<(mymbox{from}) To: %{to}%> |
---|
281 | |
---|
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. |
---|
287 | |
---|
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. |
---|
295 | |
---|
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. |
---|
305 | |
---|
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. |
---|
318 | |
---|
319 | The available output width is kept in an internal register; any output |
---|
320 | past this width will be truncated. |
---|
321 | |
---|
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) |
---|
324 | newline. |
---|
325 | |
---|
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. |
---|
329 | The first part is: |
---|
330 | |
---|
331 | .ti +.5i |
---|
332 | %4(msg)%<(cur)+%| %>%<{replied}\-%?{encrypted}E%| %> |
---|
333 | |
---|
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: |
---|
339 | |
---|
340 | .ti +.5i |
---|
341 | %02(mon{date})/%02(mday{date}) |
---|
342 | |
---|
343 | the month and date are printed in two digits (zero filled) separated by |
---|
344 | a slash. |
---|
345 | Next, |
---|
346 | |
---|
347 | .ti +.5i |
---|
348 | %<{date} %|*> |
---|
349 | |
---|
350 | If a \*(lqDate:\*(rq field was present, |
---|
351 | then a space is printed, otherwise a `*'. |
---|
352 | Next, |
---|
353 | |
---|
354 | .ti +.5i |
---|
355 | %<(mymbox{from})%<{to}To:%14(friendly{to})%>%> |
---|
356 | |
---|
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. |
---|
361 | Continuing, |
---|
362 | |
---|
363 | .ti +.5i |
---|
364 | %<(zero)%17(friendly{from})%> |
---|
365 | |
---|
366 | if either of the above two tests failed, |
---|
367 | then the \*(lqFrom:\*(rq address is printed |
---|
368 | in a \*(lquser-friendly\*(rq format. |
---|
369 | And finally, |
---|
370 | |
---|
371 | .ti +.5i |
---|
372 | %{subject}%<{body}<<%{body}%> |
---|
373 | |
---|
374 | the subject and initial body (if any) are printed. |
---|
375 | |
---|
376 | For a more complicated example, next consider |
---|
377 | the default \fIreplcomps\fR format file. |
---|
378 | |
---|
379 | .ti +.5i |
---|
380 | %(lit)%(formataddr %<{reply-to} |
---|
381 | |
---|
382 | This clears \fIstr\fR and formats the \*(lqReply-To:\*(rq header |
---|
383 | if present. If not present, the else-if clause is executed. |
---|
384 | |
---|
385 | .ti +.5i |
---|
386 | %?{from}%?{sender}%?{return-path}%>)\\ |
---|
387 | |
---|
388 | This formats the |
---|
389 | \*(lqFrom:\*(rq, \*(lqSender:\*(rq and \*(lqReturn-Path:\*(rq |
---|
390 | headers, stopping as soon as one of them is present. Next: |
---|
391 | |
---|
392 | .ti +.5i |
---|
393 | %<(nonnull)%(void(width))%(putaddr To: )\\n%>\\ |
---|
394 | |
---|
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. |
---|
398 | |
---|
399 | .ti +.5i |
---|
400 | %(lit)%(formataddr{to})%(formataddr{cc})%(formataddr(me))\\ |
---|
401 | |
---|
402 | \fIstr\fR is cleared, and the |
---|
403 | \*(lqTo:\*(rq and \*(lqCc:\*(rq headers, along with the user's |
---|
404 | address |
---|
405 | (depending on what was specified with |
---|
406 | the \*(lq\-cc\*(rq switch to \fIrepl\fR\^) are formatted. |
---|
407 | |
---|
408 | .ti +.5i |
---|
409 | %<(nonnull)%(void(width))%(putaddr cc: )\\n%>\\ |
---|
410 | |
---|
411 | If the result is non-null, it is printed as above with a |
---|
412 | leading label of \*(lqcc: \*(rq. |
---|
413 | |
---|
414 | .ti +.5i |
---|
415 | %<{fcc}Fcc: %{fcc}\\n%>\\ |
---|
416 | |
---|
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. |
---|
420 | |
---|
421 | .ti +.5i |
---|
422 | %<{subject}Subject: Re: %{subject}\\n%>\\ |
---|
423 | |
---|
424 | If a subject component was present, |
---|
425 | a suitable reply subject is output. |
---|
426 | |
---|
427 | .nf |
---|
428 | .ti +.5i |
---|
429 | %<{date}In-reply-to: Your message of "\\ |
---|
430 | .ti +.5i |
---|
431 | %<(nodate{date})%{date}%|%(pretty{date})%>."%<{message-id} |
---|
432 | .ti +.5i |
---|
433 | %{message-id}%>\\n%>\\ |
---|
434 | .ti +.5i |
---|
435 | \-\-\-\-\-\-\-\- |
---|
436 | .fi |
---|
437 | |
---|
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. |
---|
443 | |
---|
444 | This last part is a good example for a little more elaboration. |
---|
445 | Here's that part again in pseudo-code: |
---|
446 | .sp 1 |
---|
447 | .nf |
---|
448 | .in +.5i |
---|
449 | .ta .5i 1i 1.5i 2i |
---|
450 | if (comp_exists(date)) then |
---|
451 | print (\*(lqIn-reply-to: Your message of \\\*(lq\*(rq) |
---|
452 | if (not_date_string(date.value) then |
---|
453 | print (date.value) |
---|
454 | else |
---|
455 | print (pretty(date.value)) |
---|
456 | endif |
---|
457 | print (\*(lq\\\*(rq\*(rq) |
---|
458 | if (comp_exists(message-id)) then |
---|
459 | print (\*(lq\\n\\t\*(rq) |
---|
460 | print (message-id.value) |
---|
461 | endif |
---|
462 | print (\*(lq\\n\*(rq) |
---|
463 | endif |
---|
464 | .re |
---|
465 | .in -.5i |
---|
466 | .fi |
---|
467 | .sp 1 |
---|
468 | Although this seems complicated, |
---|
469 | in point of fact, |
---|
470 | this method is flexible enough to extract individual fields and print them in |
---|
471 | any format the user desires. |
---|
472 | .Fi |
---|
473 | None |
---|
474 | .Pr |
---|
475 | None |
---|
476 | .Sa |
---|
477 | scan(1), repl(1), ap(8), dp(8) |
---|
478 | .De |
---|
479 | None |
---|
480 | .Co |
---|
481 | None |
---|
482 | .En |
---|