Commit | Line | Data |
---|---|---|
dda00b2c BW |
1 | ;;; mh-scan.el --- MH-E scan line constants and utilities |
2 | ||
3 | ;; Copyright (C) 1993, 1995, 1997, | |
114f9c96 | 4 | ;; 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 |
dcf71371 | 5 | ;; Free Software Foundation, Inc. |
dda00b2c BW |
6 | |
7 | ;; Author: Bill Wohler <wohler@newt.com> | |
8 | ;; Maintainer: Bill Wohler <wohler@newt.com> | |
9 | ;; Keywords: mail | |
10 | ;; See: mh-e.el | |
11 | ||
12 | ;; This file is part of GNU Emacs. | |
13 | ||
5e809f55 | 14 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
dda00b2c | 15 | ;; it under the terms of the GNU General Public License as published by |
5e809f55 GM |
16 | ;; the Free Software Foundation, either version 3 of the License, or |
17 | ;; (at your option) any later version. | |
dda00b2c BW |
18 | |
19 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
20 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | ;; GNU General Public License for more details. | |
23 | ||
24 | ;; You should have received a copy of the GNU General Public License | |
5e809f55 | 25 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
dda00b2c BW |
26 | |
27 | ;;; Commentary: | |
28 | ||
29 | ;; This file contains constants and a few functions for interpreting | |
30 | ;; scan lines. | |
31 | ||
32 | ;;; Change Log: | |
33 | ||
34 | ;;; Code: | |
35 | ||
36 | (require 'mh-e) | |
37 | ||
38 | \f | |
39 | ||
40 | ;;; Scan Formats | |
41 | ||
42 | ;; The following scan formats are passed to the scan program if the setting of | |
43 | ;; `mh-scan-format-file' is t. They are identical except the later one makes | |
44 | ;; use of the nmh `decode' function to decode RFC 2047 encodings. If you just | |
45 | ;; want to change the column of the notations, use the `mh-set-cmd-note' | |
46 | ;; function. | |
47 | ||
48 | (defvar mh-scan-format-mh | |
49 | (concat | |
50 | "%4(msg)" | |
51 | "%<(cur)+%| %>" | |
52 | "%<{replied}-" | |
53 | "%?(nonnull(comp{to}))%<(mymbox{to})t%>" | |
54 | "%?(nonnull(comp{cc}))%<(mymbox{cc})c%>" | |
55 | "%?(nonnull(comp{bcc}))%<(mymbox{bcc})b%>" | |
56 | "%?(nonnull(comp{newsgroups}))n%>" | |
57 | "%<(zero) %>" | |
58 | "%02(mon{date})/%02(mday{date})%<{date} %|*%>" | |
59 | "%<(mymbox{from})%<{to}To:%14(friendly{to})%>%>" | |
60 | "%<(zero)%17(friendly{from})%> " | |
61 | "%{subject}%<{body}<<%{body}%>") | |
62 | "*Scan format string for MH. | |
63 | This string is passed to the scan program via the -format | |
64 | argument. This format is identical to the default except that | |
65 | additional hints for fontification have been added to the fifth | |
66 | column (remember that in Emacs, the first column is 0). | |
67 | ||
68 | The values of the fifth column, in priority order, are: \"-\" if | |
69 | the message has been replied to, t if an address on the To: line | |
70 | matches one of the mailboxes of the current user, \"c\" if the Cc: | |
71 | line matches, \"b\" if the Bcc: line matches, and \"n\" if a | |
72 | non-empty Newsgroups: header is present.") | |
73 | ||
74 | (defvar mh-scan-format-nmh | |
75 | (concat | |
76 | "%4(msg)" | |
77 | "%<(cur)+%| %>" | |
78 | "%<{replied}-" | |
79 | "%?(nonnull(comp{to}))%<(mymbox{to})t%>" | |
80 | "%?(nonnull(comp{cc}))%<(mymbox{cc})c%>" | |
81 | "%?(nonnull(comp{bcc}))%<(mymbox{bcc})b%>" | |
82 | "%?(nonnull(comp{newsgroups}))n%>" | |
83 | "%<(zero) %>" | |
84 | "%02(mon{date})/%02(mday{date})%<{date} %|*%>" | |
85 | "%<(mymbox{from})%<{to}To:%14(decode(friendly{to}))%>%>" | |
86 | "%<(zero)%17(decode(friendly{from}))%> " | |
87 | "%(decode{subject})%<{body}<<%{body}%>") | |
88 | "*Scan format string for nmh. | |
89 | This string is passed to the scan program via the -format arg. | |
90 | This format is identical to the default except that additional | |
91 | hints for fontification have been added to the fifth | |
92 | column (remember that in Emacs, the first column is 0). | |
93 | ||
94 | The values of the fifth column, in priority order, are: \"-\" if | |
95 | the message has been replied to, t if an address on the To: field | |
96 | matches one of the mailboxes of the current user, \"c\" if the Cc: | |
97 | field matches, \"b\" if the Bcc: field matches, and \"n\" if a | |
98 | non-empty Newsgroups: field is present.") | |
99 | ||
100 | \f | |
101 | ||
102 | ;;; Regular Expressions | |
103 | ||
104 | ;; Alphabetical. | |
105 | ||
106 | (defvar mh-scan-body-regexp "\\(<<\\([^\n]+\\)?\\)" | |
107 | "This regular expression matches the message body fragment. | |
108 | ||
109 | Note that the default setting of `mh-folder-font-lock-keywords' | |
110 | expects this expression to contain at least one parenthesized | |
111 | expression which matches the body text as in the default of | |
112 | \"\\\\(<<\\\\([^\\n]+\\\\)?\\\\)\". If this regular expression is | |
113 | not correct, the body fragment will not be highlighted with the | |
114 | face `mh-folder-body'.") | |
115 | ||
116 | (defvar mh-scan-cur-msg-number-regexp "^\\( *[0-9]+\\+\\).*" | |
117 | "This regular expression matches the current message. | |
118 | ||
119 | It must match from the beginning of the line. Note that the | |
120 | default setting of `mh-folder-font-lock-keywords' expects this | |
121 | expression to contain at least one parenthesized expression which | |
122 | matches the message number as in the default of | |
123 | ||
124 | \"^\\\\( *[0-9]+\\\\+\\\\).*\". | |
125 | ||
126 | This expression includes the leading space and current message | |
127 | marker \"+\" within the parenthesis since it looks better to | |
128 | highlight these items as well. The highlighting is done with the | |
129 | face `mh-folder-cur-msg-number'. This regular expression should | |
130 | be correct as it is needed by non-fontification functions. See | |
131 | also `mh-note-cur'.") | |
132 | ||
133 | (defvar mh-scan-date-regexp "\\([0-9][0-9]/[0-9][0-9]\\)" | |
134 | "This regular expression matches a valid date. | |
135 | ||
136 | It must not be anchored to the beginning or the end of the line. | |
137 | Note that the default setting of `mh-folder-font-lock-keywords' | |
138 | expects this expression to contain only one parenthesized | |
139 | expression which matches the date field as in the default of | |
140 | \"\\\\([0-9][0-9]/[0-9][0-9]\\\\)\"}. If this regular expression | |
141 | is not correct, the date will not be highlighted with the face | |
142 | `mh-folder-date'.") | |
143 | ||
144 | (defvar mh-scan-deleted-msg-regexp "^\\( *[0-9]+\\)D" | |
145 | "This regular expression matches deleted messages. | |
146 | ||
147 | It must match from the beginning of the line. Note that the | |
148 | default setting of `mh-folder-font-lock-keywords' expects this | |
149 | expression to contain at least one parenthesized expression which | |
150 | matches the message number as in the default of | |
151 | ||
152 | \"^\\\\( *[0-9]+\\\\)D\". | |
153 | ||
154 | This expression includes the leading space within the parenthesis | |
155 | since it looks better to highlight it as well. The highlighting | |
156 | is done with the face `mh-folder-deleted'. This regular | |
157 | expression should be correct as it is needed by non-fontification | |
158 | functions. See also `mh-note-deleted'.") | |
159 | ||
160 | (defvar mh-scan-good-msg-regexp "^\\( *[0-9]+\\)[^D^0-9]" | |
161 | "This regular expression matches \"good\" messages. | |
162 | ||
163 | It must match from the beginning of the line. Note that the | |
164 | default setting of `mh-folder-font-lock-keywords' expects this | |
165 | expression to contain at least one parenthesized expression which | |
166 | matches the message number as in the default of | |
167 | ||
168 | \"^\\\\( *[0-9]+\\\\)[^D^0-9]\". | |
169 | ||
170 | This expression includes the leading space within the parenthesis | |
171 | since it looks better to highlight it as well. The highlighting | |
172 | is done with the face `mh-folder-msg-number'. This regular | |
173 | expression should be correct as it is needed by non-fontification | |
174 | functions.") | |
175 | ||
176 | (defvar mh-scan-msg-format-regexp "%\\([0-9]*\\)(msg)" | |
177 | "This regular expression finds the message number width in a scan format. | |
178 | ||
179 | Note that the message number must be placed in a parenthesized | |
180 | expression as in the default of \"%\\\\([0-9]*\\\\)(msg)\". This | |
181 | variable is only consulted if `mh-scan-format-file' is set to | |
182 | \"Use MH-E scan Format\".") | |
183 | ||
184 | (defvar mh-scan-msg-format-string "%d" | |
185 | "This is a format string for width of the message number in a scan format. | |
186 | ||
187 | Use \"0%d\" for zero-filled message numbers. This variable is only | |
188 | consulted if `mh-scan-format-file' is set to \"Use MH-E scan | |
189 | Format\".") | |
190 | ||
191 | (defvar mh-scan-msg-number-regexp "^ *\\([0-9]+\\)" | |
192 | "This regular expression extracts the message number. | |
193 | ||
194 | It must match from the beginning of the line. Note that the | |
195 | message number must be placed in a parenthesized expression as in | |
196 | the default of \"^ *\\\\([0-9]+\\\\)\".") | |
197 | ||
198 | (defvar mh-scan-msg-overflow-regexp "^[?0-9][0-9]" | |
199 | "This regular expression matches overflowed message numbers.") | |
200 | ||
201 | (defvar mh-scan-msg-search-regexp "^[^0-9]*%d[^0-9]" | |
202 | "This regular expression matches a particular message. | |
203 | ||
204 | It is a format string; use \"%d\" to represent the location of the | |
205 | message number within the expression as in the default of | |
206 | \"^[^0-9]*%d[^0-9]\".") | |
207 | ||
208 | (defvar mh-scan-rcpt-regexp "\\(To:\\)\\(..............\\)" | |
209 | "This regular expression specifies the recipient in messages you sent. | |
210 | ||
211 | Note that the default setting of `mh-folder-font-lock-keywords' | |
212 | expects this expression to contain two parenthesized expressions. | |
213 | The first is expected to match the \"To:\" that the default scan | |
214 | format file generates. The second is expected to match the | |
215 | recipient's name as in the default of | |
216 | \"\\\\(To:\\\\)\\\\(..............\\\\)\". If this regular | |
217 | expression is not correct, the \"To:\" string will not be | |
218 | highlighted with the face `mh-folder-to' and the recipient will | |
219 | not be highlighted with the face `mh-folder-address'") | |
220 | ||
221 | (defvar mh-scan-refiled-msg-regexp "^\\( *[0-9]+\\)\\^" | |
222 | "This regular expression matches refiled messages. | |
223 | ||
224 | It must match from the beginning of the line. Note that the | |
225 | default setting of `mh-folder-font-lock-keywords' expects this | |
226 | expression to contain at least one parenthesized expression which | |
227 | matches the message number as in the default of | |
228 | ||
229 | \"^\\\\( *[0-9]+\\\\)\\\\^\". | |
230 | ||
231 | This expression includes the leading space within the parenthesis | |
232 | since it looks better to highlight it as well. The highlighting | |
233 | is done with the face `mh-folder-refiled'. This regular | |
234 | expression should be correct as it is needed by non-fontification | |
235 | functions. See also `mh-note-refiled'.") | |
236 | ||
237 | (defvar mh-scan-sent-to-me-sender-regexp | |
238 | "^ *[0-9]+.\\([bct]\\).....[ ]*\\(..................\\)" | |
239 | "This regular expression matches messages sent to us. | |
240 | ||
241 | Note that the default setting of `mh-folder-font-lock-keywords' | |
242 | expects this expression to contain at least two parenthesized | |
243 | expressions. The first should match the fontification hint (see | |
244 | `mh-scan-format-nmh') and the second should match the user name | |
245 | as in the default of | |
246 | ||
247 | ^ *[0-9]+.\\\\([bct]\\\\).....[ ]*\\\\(..................\\\\) | |
248 | ||
249 | If this regular expression is not correct, the notation hints | |
250 | will not be highlighted with the face | |
251 | `mh-mh-folder-sent-to-me-hint' and the sender will not be | |
252 | highlighted with the face `mh-folder-sent-to-me-sender'.") | |
253 | ||
254 | (defvar mh-scan-subject-regexp | |
255 | "^ *[0-9]+........[ ]*...................\\([Rr][Ee]\\(\\[[0-9]+\\]\\)?:\\s-*\\)*\\([^<\n]*\\)" | |
256 | "This regular expression matches the subject. | |
257 | ||
258 | It must match from the beginning of the line. Note that the | |
259 | default setting of `mh-folder-font-lock-keywords' expects this | |
260 | expression to contain at least three parenthesized expressions. | |
261 | The first is expected to match the \"Re:\" string, if any, and is | |
262 | highlighted with the face `mh-folder-followup'. The second | |
263 | matches an optional bracketed number after \"Re:\", such as in | |
264 | \"Re[2]:\" (and is thus a sub-expression of the first expression) | |
265 | and the third is expected to match the subject line itself which | |
266 | is highlighted with the face `mh-folder-subject'. For example, | |
267 | the default (broken on multiple lines for readability) is | |
268 | ||
269 | ^ *[0-9]+........[ ]*................... | |
270 | \\\\([Rr][Ee]\\\\(\\\\\\=[[0-9]+\\\\]\\\\)?:\\\\s-*\\\\)* | |
271 | \\\\([^<\\n]*\\\\) | |
272 | ||
273 | This regular expression should be correct as it is needed by | |
274 | non-fontification functions.") | |
275 | ||
276 | (defvar mh-scan-valid-regexp "^ *[0-9]" | |
277 | "This regular expression describes a valid scan line. | |
278 | ||
279 | This is used to eliminate error messages that are occasionally | |
280 | produced by \"inc\".") | |
281 | ||
282 | \f | |
283 | ||
284 | ;;; Widths, Offsets and Columns | |
285 | ||
286 | (defvar mh-cmd-note 4 | |
287 | "Column for notations. | |
288 | ||
289 | This variable should be set with the function `mh-set-cmd-note'. | |
290 | This variable may be updated dynamically if | |
291 | `mh-adaptive-cmd-note-flag' is on. | |
292 | ||
293 | Note that columns in Emacs start with 0.") | |
294 | (make-variable-buffer-local 'mh-cmd-note) | |
295 | ||
296 | (defvar mh-scan-cmd-note-width 1 | |
297 | "Number of columns consumed by the cmd-note field in `mh-scan-format'. | |
298 | ||
299 | This column will have one of the values: \" \", \"D\", \"^\", \"+\" and | |
300 | where \" \" is the default value, | |
301 | ||
302 | \"D\" is the `mh-note-deleted' character, | |
303 | \"^\" is the `mh-note-refiled' character, and | |
304 | \"+\" is the `mh-note-cur' character.") | |
305 | ||
306 | (defvar mh-scan-destination-width 1 | |
307 | "Number of columns consumed by the destination field in `mh-scan-format'. | |
308 | ||
309 | This column will have one of \" \", \"%\", \"-\", \"t\", \"c\", \"b\", or \"n\" | |
310 | in it. | |
311 | ||
312 | \" \" blank space is the default character. | |
313 | \"%\" indicates that the message in in a named MH sequence. | |
314 | \"-\" indicates that the message has been annotated with a replied field. | |
315 | \"t\" indicates that the message contains mymbox in the To: field. | |
316 | \"c\" indicates that the message contains mymbox in the Cc: field. | |
317 | \"b\" indicates that the message contains mymbox in the Bcc: field. | |
318 | \"n\" indicates that the message contains a Newsgroups: field.") | |
319 | ||
320 | (defvar mh-scan-date-width 5 | |
321 | "Number of columns consumed by the date field in `mh-scan-format'. | |
322 | This column will typically be of the form mm/dd.") | |
323 | ||
324 | (defvar mh-scan-date-flag-width 1 | |
325 | "Number of columns consumed to flag (in)valid dates in `mh-scan-format'. | |
326 | This column will have \" \" for valid and \"*\" for invalid or | |
327 | missing dates.") | |
328 | ||
329 | (defvar mh-scan-from-mbox-width 17 | |
330 | "Number of columns consumed with the \"From:\" line in `mh-scan-format'. | |
331 | This column will have a friendly name or e-mail address of the | |
332 | originator, or a \"To: address\" for outgoing e-mail messages.") | |
333 | ||
334 | (defvar mh-scan-from-mbox-sep-width 2 | |
335 | "Number of columns consumed by whitespace after from-mbox in `mh-scan-format'. | |
336 | This column will only ever have spaces in it.") | |
337 | ||
338 | (defvar mh-scan-field-destination-offset | |
339 | (+ mh-scan-cmd-note-width) | |
340 | "The offset from the `mh-cmd-note' for the destination column.") | |
341 | ||
342 | (defvar mh-scan-field-from-start-offset | |
343 | (+ mh-scan-cmd-note-width | |
344 | mh-scan-destination-width | |
345 | mh-scan-date-width | |
346 | mh-scan-date-flag-width) | |
347 | "The offset from the `mh-cmd-note' to find the start of \"From:\" address.") | |
348 | ||
349 | (defvar mh-scan-field-from-end-offset | |
350 | (+ mh-scan-field-from-start-offset mh-scan-from-mbox-width) | |
351 | "The offset from the `mh-cmd-note' to find the end of \"From:\" address.") | |
352 | ||
353 | (defvar mh-scan-field-subject-start-offset | |
354 | (+ mh-scan-cmd-note-width | |
355 | mh-scan-destination-width | |
356 | mh-scan-date-width | |
357 | mh-scan-date-flag-width | |
358 | mh-scan-from-mbox-width | |
359 | mh-scan-from-mbox-sep-width) | |
360 | "The offset from the `mh-cmd-note' to find the start of the subject.") | |
361 | ||
362 | \f | |
363 | ||
364 | ;;; Notation | |
365 | ||
366 | ;; Alphabetical. | |
367 | ||
368 | (defvar mh-note-cur ?+ | |
369 | "The current message (in MH, not in MH-E) is marked by this character. | |
370 | See also `mh-scan-cur-msg-number-regexp'.") | |
371 | ||
3bdb2567 | 372 | (defvar mh-note-copied ?C |
dda00b2c BW |
373 | "Messages that have been copied are marked by this character.") |
374 | ||
375 | (defvar mh-note-deleted ?D | |
376 | "Messages that have been deleted are marked by this character. | |
377 | See also `mh-scan-deleted-msg-regexp'.") | |
378 | ||
379 | (defvar mh-note-dist ?R | |
380 | "Messages that have been redistributed are marked by this character.") | |
381 | ||
382 | (defvar mh-note-forw ?F | |
383 | "Messages that have been forwarded are marked by this character.") | |
384 | ||
3bdb2567 | 385 | (defvar mh-note-printed ?P |
dda00b2c BW |
386 | "Messages that have been printed are marked by this character.") |
387 | ||
388 | (defvar mh-note-refiled ?^ | |
389 | "Messages that have been refiled are marked by this character. | |
390 | See also `mh-scan-refiled-msg-regexp'.") | |
391 | ||
392 | (defvar mh-note-repl ?- | |
393 | "Messages that have been replied to are marked by this character.") | |
394 | ||
395 | (defvar mh-note-seq ?% | |
396 | "Messages in a user-defined sequence are marked by this character. | |
397 | ||
398 | Messages in the \"search\" sequence are marked by this character as | |
399 | well.") | |
400 | ||
401 | \f | |
402 | ||
403 | ;;; Utilities | |
404 | ||
405 | ;;;###mh-autoload | |
406 | (defun mh-scan-msg-number-regexp () | |
407 | "Return value of variable `mh-scan-msg-number-regexp'." | |
408 | mh-scan-msg-number-regexp) | |
409 | ||
410 | ;;;###mh-autoload | |
411 | (defun mh-scan-msg-search-regexp () | |
412 | "Return value of variable `mh-scan-msg-search-regexp'." | |
413 | mh-scan-msg-search-regexp) | |
414 | ||
415 | ;;;###mh-autoload | |
416 | (defun mh-set-cmd-note (column) | |
417 | "Set `mh-cmd-note' to COLUMN. | |
418 | Note that columns in Emacs start with 0." | |
419 | (setq mh-cmd-note column)) | |
420 | ||
421 | ;;;###mh-autoload | |
422 | (defun mh-scan-format () | |
423 | "Return the output format argument for the scan program." | |
424 | (if (equal mh-scan-format-file t) | |
143578ae | 425 | (list "-format" (if (mh-variant-p 'nmh 'gnu-mh) |
dda00b2c BW |
426 | (list (mh-update-scan-format |
427 | mh-scan-format-nmh mh-cmd-note)) | |
428 | (list (mh-update-scan-format | |
429 | mh-scan-format-mh mh-cmd-note)))) | |
430 | (if (not (equal mh-scan-format-file nil)) | |
431 | (list "-form" mh-scan-format-file)))) | |
432 | ||
433 | (defun mh-update-scan-format (fmt width) | |
434 | "Return a scan format with the (msg) width in the FMT replaced with WIDTH. | |
435 | ||
436 | The message number width portion of the format is discovered | |
437 | using `mh-scan-msg-format-regexp'. Its replacement is controlled | |
438 | with `mh-scan-msg-format-string'." | |
439 | (or (and | |
440 | (string-match mh-scan-msg-format-regexp fmt) | |
441 | (let ((begin (match-beginning 1)) | |
442 | (end (match-end 1))) | |
443 | (concat (substring fmt 0 begin) | |
444 | (format mh-scan-msg-format-string width) | |
445 | (substring fmt end)))) | |
446 | fmt)) | |
447 | ||
448 | ;;;###mh-autoload | |
449 | (defun mh-msg-num-width (folder) | |
450 | "Return the width of the largest message number in this FOLDER." | |
451 | (or mh-progs (mh-find-path)) | |
452 | (let ((tmp-buffer (get-buffer-create mh-temp-buffer)) | |
453 | (width 0)) | |
b5553d47 | 454 | (with-current-buffer tmp-buffer |
dda00b2c BW |
455 | (erase-buffer) |
456 | (apply 'call-process | |
457 | (expand-file-name mh-scan-prog mh-progs) nil '(t nil) nil | |
458 | (list folder "last" "-format" "%(msg)")) | |
459 | (goto-char (point-min)) | |
460 | (if (re-search-forward mh-scan-msg-number-regexp nil 0 1) | |
461 | (setq width (length (buffer-substring | |
462 | (match-beginning 1) (match-end 1)))))) | |
463 | width)) | |
464 | ||
465 | ;;;###mh-autoload | |
466 | (defun mh-msg-num-width-to-column (width) | |
467 | "Return the column for notations given message number WIDTH. | |
468 | Note that columns in Emacs start with 0. | |
469 | ||
470 | If `mh-scan-format-file' is set to \"Use MH-E scan Format\" this | |
471 | means that either `mh-scan-format-mh' or `mh-scan-format-nmh' are | |
472 | in use. This function therefore assumes that the first column is | |
473 | empty (to provide room for the cursor), the following WIDTH | |
474 | columns contain the message number, and the column for notations | |
475 | comes after that." | |
476 | (if (eq mh-scan-format-file t) | |
477 | (max (1+ width) 2) | |
478 | (error "%s %s" "Can't call `mh-msg-num-width-to-column' when" | |
479 | "`mh-scan-format-file' is not set to \"Use MH-E scan Format\""))) | |
480 | ||
481 | (provide 'mh-scan) | |
482 | ||
483 | ;; Local Variables: | |
484 | ;; indent-tabs-mode: nil | |
485 | ;; sentence-end-double-space: nil | |
486 | ;; End: | |
487 | ||
a1ab640d | 488 | ;; arch-tag: 5ab35d46-101e-443b-a2b6-5a908cf97528 |
dda00b2c | 489 | ;;; mh-scan.el ends here |