DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦e50635aac⟧ TextFile

    Length: 23176 (0x5a88)
    Types: TextFile
    Names: »mail.el«

Derivation

└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
    └─⟦32c6b6024⟧ »./gnews-2.0-tar.Z« 
        └─⟦5d06bd818⟧ 
            └─⟦this⟧ »gnews-2.0/mail.el« 

TextFile

;;; mail.el: mail-mode compatible Gnews reply commands
;;; Copyright (C) 1987, 1988 by Matthew P Wiener; all rights reserved.

;;; Send bugs, complaints, suggestions etc to weemba@garnet.berkeley.edu

;; Gnews is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY.  No author or distributor accepts responsibility to
;; anyone for the consequences of using it or for whether it serves any
;; particular purpose or works at all, unless he says so in writing.
;; Refer to the Gnews General License for full details.

;; Everyone is granted permission to copy, modify and redistribute Gnews,
;; but only under the conditions described in the Gnews General License.
;; A copy of this license is supposed to have been given to you along with
;; Gnews so you can know your rights and responsibilities.  It should be
;; accessible with the key sequence "ESC l l" while in News mode.  Among 
;; other things, the copyright notice and this notice must be preserved on
;; all copies.
\f


(provide 'gnews-mail)

;;; basic reply variables

(defvar reply-prefix ">"		; duplicated from Init.el
  "*String to indent replies with")	; for sake of mail-modes
(defvar reply-prefix-forward ">"
  "*String for indenting forwarded replies with")
(defvar reply-digest-separator "----------------"
  "*Digest article separating string")
(defvar reply-prefix-match "^a-zA-Z0-9([$`'\""
  "*Characters that define prefixes for \\[reply-split-line]")
(defvar reply-prefix-initials "[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?[a-zA-Z]?>")
(defvar reply-prefix-fill "[^a-zA-Z0-9([$`'\"]*[ \t]*"
  "*Regexp that defines prefixes for \\[reply-yank-fill]")

(defvar reply-max-back-name 60
  "*Distance from end to look for user's name when inhibiting signatures.")
(defvar reply-max-back-ps 500
  "*Distance from end to look for a postscript when inhibiting signatures.")
(defvar reply-ps-match
  (concat "^\\(" (regexp-quote reply-prefix) "\\)?\\(p[. ]*\\)+s[^a-z]")
  "*Regexp that matches postscript beginnings")

(defvar reply-signature-inhibitions
  '(reply-inhibit-name reply-inhibit-login reply-inhibit-ps)
  "*List of functions that must all come out nil before adding a
signature via \\[reply-signature].\n
The default inhibitions provided with Gnews return t when your first
name occurs within the last reply-max-back-name characters of the end,
or either your banged login name or a postscript occurs within the last
max-back-ps characters of the end.\n
Signature inhibition can be overridden by invoking \\[reply-signature] \
directly.\n
Postscripts are defined as whatever matches the regexp reply-ps-match.\n")

(defvar reply-valediction "-"
  "*String to prepend very brief signatures with--no newline is inserted")
(defvar reply-signature-separator "-- "
  "*String to prepend long signatures with--a newline is inserted")

(defvar reply-signature-default-major (concat gnews-dot-dir ".signature")
  "*The primary default signature file.")

(defvar reply-signature-default-minor '(t . "")
  "*A dotted pair describing the secondary default signature.  See
the two variables {e,n}-reply-signature-prefix-pointers for the
conditions in which the secondary default signature is appended.\n
Its car, if nil, means to use a file (looked for in the standard
places ($DOTDIR,$HOME)) that contains the signature.  If its car is
non-nil, it means to expect a literal string to use as signature.\n
The cdr is either a string (either the name of a file, in case the
car were nil, or the very signature itself, if the car were non-nil)
or a function, whose return value is the appropriate string.\n
The provided default is '(t.\"\"), for usage with inews, which
appends signatures automatically.  For raw news posters that do not
appends signatures, the default should be '(nil.\".signature\").")

(defvar e-reply-signature-prefix-pointers (list 0 nil nil 1)
  "*A list of the values of arguments to \\[reply-send] which mean, in E-Reply
mode, to append no signature, to append the user's first name only, to
append the user's full name, and to append the primary default signature
file respectively.  If the argument to \\[reply-send] does not match any of
the members of this list, then append the secondary default signature.\n
The primary default is the value of reply-signature-default-major; the
secondary default is coded in the value of reply-signature-default-minor,
In the case of user's first/full name, the string reply-valediction is
prepended.\n
The default is set up so that an explicit argument 0 suppresses the
signature, no argument appends the default signature file, and any
other argument appends the secondary default signature.")

(defvar n-reply-signature-prefix-pointers (list 0 nil nil nil)
  "*A list of the values of arguments to \\[reply-send] which mean, in N-Reply
mode, to append no signature, to append the user's first name only, to
append the user's full name, and to append the primary default signature
file respectively.  If the argument to \\[reply-send] does not match any of
the members of this list, then append the secondary default signature.\n
The primary default is the value of reply-signature-default-major; the
secondary default is coded in the value of reply-signature-default-minor,
In the case of user's first/full name, the string reply-valediction is
prepended.\n
The default is set up so that an explicit argument 0 suppresses the
signature, and anything else invokes the secondary default mechanism.
(Which also defaults to no signature.  In other words, things are set
up so that inews appends your signature for you.  If you use a different
posting mechanism, for example, if n-reply-program is nil, then you
should change your defaults to be more like the E-Reply defaults.)")

(defvar reply-signature-point (set-marker (make-marker) 1)
  "Marker at the beginning of the signature just after its insertion.")
\f


;;; path aliasing--not for everyone

(provide 'gnews-mail)

(defconst path-buffer-name "*gnews*path*" "Internal path-finding buffer")

(defun path-alias (site)
  "Turns \"SITE\" into \"path!SITE\"."
  ;; This assumes that "telnet PATH-HOST PATH-SERVICE" is around.  See
  ;; RFC 915.  If you have a different way of pathaliasing, then rewrite.
  (let* ((b (current-buffer))
	 (path-buffer (generate-new-buffer path-buffer-name))
	 (path-finder (open-network-stream
		       "path-finder" path-buffer path-host path-service))
	 p)
    (accept-process-output path-finder)
    (send-string path-finder (concat "path " site "\n"))
    (accept-process-output path-finder)
    (delete-process path-finder)
    (set-buffer path-buffer)
    (goto-char (point-max))
    (previous-line 1)
    (prog2
	(setq p (point))
	(if (string= "220" (buffer-substring p (+ 3 p)))
	    (buffer-substring (+ 4 p) (- (point-max) 5)))
      (set-buffer b)
      (kill-buffer path-buffer))))

(defun reply-path-alias (pfx)
  "Look for the standard UUCP map path to the site name bounding point,
and if found, insert it."
  (interactive "*P")
  (if pfx
      (progn
	(end-of-line)
	(search-backward "!")
	(insert ".ATT.COM"))
    (backward-char)
    (if (looking-at "[! ]")
	(forward-char)
      (forward-char)
      (backward-word 1))
    (let ((path (path-alias (buffer-substring
			      (point) (save-excursion
					(forward-word 1) (point))))))
      (if (not path)
	  (message "unknown site" (ding))
	(gnews-delete-word)
	(insert path)))))

(defvar path-uucp nil
  "*A list of your UUCP neighbors, as symbols.")
(defvar path-arpa nil
  "*An alist of site names (symbols) and their domainized forms (strings).")
(defvar path-hops nil
  "*An alist of site names (symbols) to UUCP paths (strings).")
(defvar path-all nil
  "The list of known sites to internal path aliasing, as symbols.")

(defvar path-data-file "your.path.file"
  "*File containing some simple path aliasing rules.\n
Its contents must look something like the following:\n
  (setq path-uucp '(ucdavis ucsbcsl usenix trwrb tolerant alice ...))
  (setq path-arpa '((uunet . \"uunet.uu.net\") (ames . \"arc.nasa.gov\") ...)
  (setq path-hops '((killer . \"decwrl\") (snark . \"uunet!cbmvax\") ...))\n
That is, path-uucp is a list of your UUCP neighbors, path-arpa is an alist
of domainized conversions (ARPA or not), and path-hops is an alist of UUCP
paths to get to the indicated sites.")

(defun reply-to-simplify (&optional pfx recurse)
  "To/Cc/Bcc simplifier."
  (interactive "*P")
  (beginning-of-line)
  (if (looking-at "^\\(to\\|b?cc\\): ") nil
    (e-reply-position-on-field "to")
    (beginning-of-line)
    (re-search-forward "^\\(to\\|b?cc\\): "))
  (if (looking-at "^\\(to\\|b?cc\\): \\([^@\n]+\\)@\\([^@\n]+\\)\\.uucp$")
      (replace-match "\\1: \\2%\\3.uucp@uunet.UU.NET")
    (if path-all nil
      (load path-data-file nil t)
      (setq path-all (append path-uucp
			     (mapcar 'car path-arpa)
			     (mapcar 'car path-hops))))
    (let ((bolpoint (match-end 1)) eolpoint
	  site arpa p name lead site-name-length @ok)
      (goto-char bolpoint)
      (just-one-space)
      (insert ?!)
      (setq bolpoint (1- (point)))
      (end-of-line)
      (setq eolpoint (point) @ok)
      (if (search-backward "%" bolpoint t)
	  (progn
	    (replace-match "@")
	    (if (re-search-forward "\\..*@" eolpoint t)
		nil
	      (setq @ok t)
	      (if (search-forward "@" eolpoint t) (replace-match ".")))))
      (if (and (not @ok) (search-backward "@" bolpoint t))
	  (progn (gnews-delete-line) (newline)))
      (search-backward "!" bolpoint t)
      (if (not pfx)
	  (while (and (not site)
		  (not arpa)
		  (setq p (point))
		  (search-backward "!" bolpoint t))
	(setq name (buffer-substring (1+ (point)) p)
	      site (car (memq (car (read-from-string name)) path-all))
	      arpa (if (save-excursion (search-forward "." p t))
		       name (cdr (assq site path-arpa)))
	      lead (or (cdr (assq site path-hops))))
	(if (and recurse lead)
	    (setq site nil lead nil))
	(cond ((or site arpa)
	       (setq site-name-length (- p (point)))
	       (forward-char 1)
	       (cond (arpa
		      (delete-backward-char (- (point) bolpoint))
		      (delete-backward-char (- site-name-length))
		      (end-of-line)
		      (insert ?@ arpa))
		     (lead
		      (delete-backward-char (- (point) bolpoint))
		      (insert lead ?!)
		      (reply-to-simplify nil t))
		     (site
		      (delete-backward-char (- (point) bolpoint)))))))
	(insert ".att.com")
	(reply-to-simplify nil t))))
  (if (looking-at "!") (delete-char 1 t)))
\f


;; blurbs

(defvar reply-blurb '(reply-short-blurb reply-long-blurb)
  "*List of blurb functions")

(defun reply-short-blurb ()
  "Insert a brief identifying blurb for quoted material."
  (goto-char reply-yank-min)
  (open-line 1)
  (insert ?\n "In " (if (gnews-digest-p) "" "article ")
	  (article-field "Message-ID"))
  (if (or (eq major-mode 'n-reply-mode)
	  (eq this-command 'group-follow-yank))
      (insert ", " (reply-domain (article-field "From")) " writes:")
    (insert " you write:")
    (forward-char 1)))

(defun reply-long-blurb ()
  "Insert a long identifying blurb for quoted material."
  (goto-char reply-yank-min)
  (open-line 1)
  (insert "From: " (article-field "From") ?\n
	  "Subject: " (article-field "Subject") ?\n)
  (if (gnews-digest-p) nil
    (insert "Message-ID: " (article-field "Message-ID") ?\n))
  (forward-char 1))
\f


;;; headers

(defun reply-position-on-field (field pos)
  "Move to end of header labeled FIELD if POS is non-nil, or to the
beginning of the field if POS is nil."
  (if (<= (article-min) (point))	; save old position
      (set-marker reply-body-marker (point)))
  (goto-char (marker-position reply-begin-marker))
  (if (re-search-forward (concat "^" (regexp-quote field) ":") (article-min) t)
      (if pos
	  (end-of-line)
	(beginning-of-line)
	(search-forward ":")
	(forward-char 1))
    (forward-paragraph 1)
    (insert field ": \n")
    (backward-char 1)))

(defun e-reply-position-on-field (field &optional pos)
  "Like mail-position-on-field, but with the mail-header-separator
set to the empty string, as in Rnmail."
  (let ((mail-header-separator "")) (mail-position-on-field field pos)))
\f


;;; signature handling

(defun reply-inhibit-name ()
  "Return non-nil iff user's first name is within reply-max-back-name chars."
  (search-backward (progn
		     (string-match "\\<[^ ]*\\>" (user-full-name))
		     (substring (user-full-name)
				(match-beginning 0) (match-end 0)))
		   (max (- (point-max) reply-max-back-name) max-back-search)
		   t))

(defun reply-inhibit-login ()
  "Return non-nil iff user's login name is within reply-max-back-name chars."
  (search-backward (concat "!" (user-login-name))
		   (max (- (point-max) reply-max-back-ps) max-back-search)
		   t))

(defun reply-inhibit-ps ()
  "Return non-nil iff a postscript is within reply-max-back-ps chars."
  (re-search-backward reply-ps-match
		      (max (- (point-max) reply-max-back-ps) max-back-search)
		      t))

(defun reply-signature (mustsign &optional sigpair)
  "Append a signature.\n
If MUSTSIGN is non-nil, or this function is run interactively, then do
not look through the reply-signature-inhibitions, which see.  Optional
argument SIGPAIR is a dotted pair in reply-signature-default-minor format."
  (interactive (list t))
  (setq reply-position (point))
  (goto-char (point-max))
  (if (/= ?\n (or (char-after (1- (point-max))) 0)) (insert ?\n))
  (let ((max-back-search (save-excursion
			   (goto-char 1)
			   (if (or (string-match "*gnews*" (buffer-name))
				   (zerop (length mail-header-separator)))
			       (forward-paragraph)
			     (search-forward mail-header-separator))
			   (forward-line 1)
			   (point)))
	(ihl reply-signature-inhibitions)
	(inh t))
    (if (or mustsign
	    (progn
	      (while (and ihl inh)
		(setq inh (not (condition-case nil
				   (funcall (car ihl))
				 (error nil)))
		      ihl (cdr ihl)))
	      inh))
	(reply-signature-insert sigpair))))

(defun reply-signature-insert (&optional sigpair)
  "Insert a signature at point, as coded by SIGPAIR.  If SIGPAIR is nil,
use the pair reply-signature-default-minor."
  (interactive)
  (setq sigpair (or sigpair reply-signature-default-minor))
  (let ((p (point))
	(s (cdr sigpair)))
    (if (car sigpair)
	(insert				; get from a string
	  (cond ((stringp s) s)
		((fboundp s) (setq s (funcall s)))))
      (condition-case ()
	  (insert-file			; get from a file
	    (expand-file-name
	      (cond ((stringp s) (concat (or (getenv "DOTDIR")
					     (getenv "HOME") "~")
					 "/" s))
		    ((fboundp s) (setq s (funcall s))))))
	(file-error (if (y-or-n-p "Signature file error, proceed? ")
			(setq s "")
		      (error "")))))
    (if (zerop (length s))
	(set-marker reply-signature-marker (point))
      (goto-char p)
      (open-line 2)
      (delete-blank-lines)
      (set-marker reply-signature-marker (point))
      (insert reply-signature-separator))))

(defun reply-signature-default-pair (arg sig-pfx-ptr)
  "Set the signature pair based on ARG and SIG-PFX-PTR list.\n
This means:
 * If ARG = member 0 of SIG-PFX-PTR, append no signature.
 * If ARG = member 1 of SIG-PFX-PTR, append user's first name.
 * If ARG = member 2 of SIG-PFX-PTR, append user's full name.
 * If ARG = member 3 of SIG-PFX-PTR, append reply-signature-default-major.
 * If ARG isn't a member of SIG-PFX-PTR, use reply-signature-default-minor."
  (cond ((eq arg (nth 0 sig-pfx-ptr))		; no signature
	 (cons t ""))
	((eq arg (nth 1 sig-pfx-ptr))		; first name only
	 (cons t (concat reply-valediction
			 (progn
			   (string-match "\\<[^ ]*\\>" (user-full-name))
			   (substring (user-full-name)
				      (match-beginning 0) (match-end 0)))
			 "\n")))
	((eq arg (nth 2 sig-pfx-ptr))		; formal name
	 (cons t (concat reply-valediction (user-full-name) "\n")))
	((eq arg (nth 3 sig-pfx-ptr))		; default file
	 (cons nil reply-signature-default-major))
	(t					; fancy signature
         reply-signature-default-minor)))

(defun reply-fluff ()
  "Remove unneeded white-space."
  (interactive)
  (save-excursion
    (goto-char 1)
    (while (re-search-forward "[ \t]+$" nil t)
      (delete-region (match-beginning 0) (point)))
    (goto-char (point-max))
    (while (looking-at "^$") (gnews-delete-line) (forward-line -1))))
\f


;;; toggle between {e,n}-reply

(defun n-reply-toggle (pfx)
  "Redo the current headers so that they are appropriate for mailing,
and change to e-reply-mode."
  (interactive "P")
  (run-hooks 'group-reply-start-hook)
  (let (to subj ngs inrep)
    (e-reply-mode)
    (goto-char 1)
    (gnews-delete-paragraph)
    (setq to (article-to)
	  subj (reply-re-0 (article-field "Subject"))
	  ngs (article-field "Newsgroups")
	  inrep (article-field "Message-ID")
	  this-command 'n-reply-toggle)
    (insert "To: " to ?\n)
    (if mail-default-reply-to
	(insert "Reply-to: " mail-default-reply-to ?\n))
    (if mail-self-blind
	(insert "Bcc: " (user-login-name) ?\n))
    (if mail-archive-file-name
	(insert "Fcc: " mail-archive-file-name ?\n))
    (insert "Subject: " (if (string= subj "") "" (concat "Re: " subj)) ?\n
	    "Newsgroups: " ngs ?\n
	    "In-Reply-To: " inrep ?\n
	    "Organization: " gnews-organization ?\n))
  (set-buffer-modified-p t)
  (sit-for 0)
  (run-hooks 'group-reply-hook))

(defun e-reply-toggle (pfx)
  "Redo the current headers so that they are appropriate for posting,
and change to n-reply-mode.\n
With prefix argument, leave the first two headers in place, so that
simultaneous posting/mailing takes place."
  (interactive "P")
  (if (not n-reply-allowed)
      (error "Sorry, but posting is not allowed.")
    (run-hooks 'group-follow-start-hook)
    (let (p subj ngs from refs repto msgid org key wasfrom folup goal-column)
      (n-reply-mode)
      (goto-char 1)
      (e-reply-position-on-field "Subject")
      (setq p (point))
      (re-search-backward "^Subject: ")
      (setq subj (buffer-substring (+ 9 (point)) p))
      (goto-char 1)
      (if pfx
	  (progn
	    (forward-line 2)
	    (insert "\n")))
      (gnews-delete-paragraph)
      (setq ngs (article-field "Followup-To" "Newsgroups")
	    from (concat gnews-user "@" (reply-domain gnews-machine)
			 " (" gnews-name ")")
	    refs (article-field "References")
	    msgid (article-field "Message-ID")
	    refs (if (string= refs "") msgid (concat refs " " msgid))
	    repto (concat gnews-user "@" gnews-machine " (" gnews-name ")")
	    org gnews-organization
	    key (article-field "Keywords")
	    wasfrom (article-field "From")
	    dist (article-field "Distribution")
	    folup (let ((i (string-match "," ngs)))
		    (if i (substring ngs 0 i) ""))
	    this-command 'e-reply-toggle)
      (insert "Newsgroups: " ngs ?\n
	      "From: " from ?\n
	      "Subject: " subj ?\n
	      "Summary: \n"
	      "Expires: \n"
	      "References: " refs ?\n
	      "Sender: \n"
	      "Reply-To: " repto ?\n
	      "Followup-To: " folup ?\n
	      (if (string< "" wasfrom)
		  (concat "In-reply-to: " wasfrom "\n")
		"")
	      "Distribution: " dist ?\n
	      "Organization: " gnews-organization ?\n
	      "Keywords: " key
	      (if gnews-advertise
		  (concat "\nPosting-Front-End: Gnews " gnews-version) "")
	      "\n"))
    (set-buffer-modified-p t)
    (sit-for 0)
    (run-hooks 'group-follow-hook)))
\f


;;; indented lines

(defvar reply-paragraph-start
  "^[^a-zA-Z0-9]*\\($\\|In .*\\(article\\|digest\\)\\|.*writes:$\\)")

(defun reply-yank-fill (pfx)
  "Reformat the current paragraph, trying to identify the fill-prefix
to use automatically.  Hit return if the displayed prefix is correct,
otherwise change it.\n
Non-nil prefix argument means to also right-justify.\n
It can't deal with one-line paragraphs."
  (interactive "*P")
  (let (p q r s fill-prefix list-of-lines)
    (forward-char 1)
    (while (not (looking-at reply-paragraph-start))
      (forward-line -1))
    (forward-line 1)
    (setq p (point))
    (while (and (not (eobp)) (not (looking-at reply-paragraph-start)))
      (setq r (point))
      (end-of-line)
      (setq s (point))
      (untabify r s)
      (setq s (point))
      (setq list-of-lines (cons (list (buffer-substring r s))
				list-of-lines))
      (forward-char 1))
    (setq q (point))
    (if list-of-lines
	(progn
	  (if (< 1 (length list-of-lines)) nil
	    (setq r (string-match (concat "^[" reply-prefix-match "]*"
					  reply-prefix-initials)
				  (gnaar list-of-lines)))
	    (if r (setq list-of-lines (list (list
					      (substring (gnaar list-of-lines)
							 0 (match-end 0)))))))
	  (setq fill-prefix (read-string
			      "Fill-prefix: "
			      (try-completion "" list-of-lines)))
	  (goto-char p)
	  (while (not (looking-at (concat "^" (regexp-quote fill-prefix))))
	    (forward-line 1))
	  (setq p (point))
	  (goto-char q)
	  (forward-line -1)
	  (while (not (looking-at (concat "^" (regexp-quote fill-prefix))))
	    (forward-line -1))
	  (forward-line 1)
	  (setq q (point))
	  (if (< p q) (fill-region-as-paragraph p q pfx))))))

(defun reply-indent (beg end &optional arg)
  "Indent region with reply-prefix.  Leaves point at end.  By default
no identifying blurb is put on top--but with <nn> \\[universal-argument]'s,
then the <nn>'th blurb function is invoked.\n
For simplicity, indentation only refers to whole lines.  If the beginning
of the region is in the middle of a line, the region will be redefined
to include the beginning of the line."
  (interactive "r\np")
  (goto-char beg)
  (if (bolp) nil
    (beginning-of-line)
    (setq beg (point)))
  (set-mark end)
  (save-excursion
    (save-restriction
      (narrow-to-region beg end)
      (while (not (eobp))
	(insert reply-prefix)
	(forward-line 1))
      (let ((blurb (gnews-arg-count (or arg 1)))
	    (reply-yank-min beg)
	    (reply-yank-max end))
	(if (< 0 blurb)
	    (progn
	      (funcall (nth (1- (min (length reply-blurb) blurb)) reply-blurb))
	      (goto-char beg)		; most (all!) blurbs open an extra line
	      (gnews-delete-line))))))
  (exchange-point-and-mark))

(defun reply-split-line (p &optional arg)
  "Without a prefix argument, split the line at point, while preserving
the line's prefix and inserting three blank lines.  With a prefix argument,
blank the line backwards from point to the line's prefix.\n
A line's prefix is defined as that part of the line which preceeds the
regexp reply-prefix-match."
  (interactive "*d\nP")
  (if (eolp)
      (progn (open-line 3) (forward-line 2))	; now that was easy
    (let (goal-column blank line)		; forward-line must be vertical
      (untabify (gnews-bol) p)			; must get the char count exact
      (setq p (point))
      (if arg nil
	(beginning-of-line)
	(setq line (buffer-substring (point) (gnews-eol)))
	(goto-char p)
	(delete-region (point) (gnews-eol))
	(insert ?\n line)
	(goto-char p)
	(next-line 1)				; vertical motion down
	(setq p (point)))
      (beginning-of-line)			; second copy in place
      (skip-chars-forward reply-prefix-match)
      (if (looking-at reply-prefix-initials)
	  (goto-char (match-end 0)))		; funky initials prefix
      (setq blank (- p (point)))		; got past the prefix
      (delete-char blank)
      (insert-char ?  blank)			; blank first part
      (tabify (gnews-bol) p)
      (beginning-of-line)
      (if arg nil
	(open-line 3)
	(forward-line 1)))))