Xref: utzoo comp.emacs:8802 gnu.emacs:3417 Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!cme!durer!warsaw From: warsaw@cme.nist.gov (Barry A. Warsaw) Newsgroups: comp.emacs,gnu.emacs Subject: Supercite 2.1 public release (shar 02 of 02) Message-ID: Date: 3 Aug 90 03:28:35 GMT Sender: news@cme.nist.gov Organization: National Institute of Standards and Technology Lines: 1911 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'supercite.el' <<'END_OF_FILE' X;; ====================================================================== X;; supercite.el -- Version 2.1 X X;; ========== Introduction ========== X;; Citation and attribution package for various GNU emacs news and X;; electronic mail readers. It has been tested with these commonly X;; available news and mail readers: VM 4.41, GNUS 3.13 and RMAIL X;; 18.55. It will interface to VM 4.40+ with no modifications, but X;; with GNUS 3.12+ and RMAIL 18.55 modifications to distribution files X;; emacs/lisp/{sendmail,rnewspost}.el of GNU emacs version 18.55 are X;; required. Modifications are also required for mh-e users. These X;; modifications are supplied as diff files and as overload functions. X;; See the file sc-oloads.el for more information on overloading. See X;; the README file for more information on installing patches. X X;; This package does not do any yanking of messages, but instead X;; massages raw reply buffers set up by the reply/forward functions in X;; the news/mail reader package. Supercite is invoked via a hook. See X;; the README file for more information on how to meet the interface X;; if you are writing a reader package, or want to link supercite with X;; a reader. X X;; ========== Disclaimer ========== X;; This software is distributed in the hope that it will be useful, X;; but WITHOUT ANY WARRANTY. No author or distributor accepts X;; responsibility to anyone for the consequences of using it or for X;; whether it serves any particular purpose or works at all, unless he X;; says so in writing. X X;; Some of this software was written as part of the supercite author's X;; official duty as an employee of the United States Government and is X;; thus in the public domain. You are free to use that particular X;; software as you wish, but WITHOUT ANY WARRANTY WHATSOEVER. It X;; would be nice, though if when you use any of this code, you give X;; due credit to the author. X X;; Other parts of this code were written by other people. Wherever X;; possible, credit to that author, and the copy* notice supplied by X;; the author are included with that code. X X;; ========== Author (unless otherwise stated) ========== X;; NAME: Barry A. Warsaw USMAIL: National Institute of X;; TELE: (301) 975-3460 Standards and Technology X;; UUCP: uunet!cme.nist.gov!warsaw Rm. B-124, Bldg. 220 X;; INET: warsaw@cme.nist.gov Gaithersburg, MD 20899 X X;; Want to be on the Supercite mailing list? X;; X;; Send articles to supercite@cme.nist.gov or uunet!cme.nist.gov!supercite X;; Send administrative queries/requests to supercite-request@cme.nist.gov X;; or uunet!cme.nist.gov!supercite-request X X;; ========== Credits and Thanks ========== X;; This package was derived from the Superyank 1.11 package as posted X;; to the net. Superyank 1.11 was inspired by code and ideas from X;; Martin Neitzel and Ashwin Ram. It has been migrated to Supercite X;; 2.1 through the comments and suggestions of the supercite mailing X;; list which consists of many authors and users of the various mail X;; and news reading packages. X X;; Many folks on the supercite mailing list have contributed their X;; help in debugging, making suggestions and supplying support code or X;; bug fixes for the previous versions of supercite. I want to thank X;; everyone who helped, especially: X;; X;; Mark Baushke, Khalid Sattar, David Lawrence, Chris Davis, Kyle X;; Jones, Kayvan Sylvan, and Masanobu Umeda. X;; X;; I don't mean to leave anyone out. All who have helped have been X;; appreciated. X X;; ====================================================================== X;; Wish list for version 2.2: X;; X;; 1) handle multiple yanking into a single reply buffer. perhaps have a X;; stack for sc-gal-information (didn't get to it in 2.1). X;; X;; 2) correct for unix mail(1) putting > in front of From lines. Is it X;; really supercite's job? X X;; ====================================================================== X;; require and provide features and autoload X;; X(require 'baw-alist) X(provide 'supercite) X X X;; ********************************************************************** X;; start of user defined variables X;; ********************************************************************** X X(defvar sc-nested-citation-p nil X "*Controls whether to use nested or non-nested citation style. XNon-nil uses nested citations, nil uses non-nested citations. Nested Xcitations are of the style: X X I wrote this X > He wrote this X >> She replied to something he wrote X XNon-nested citations are of the style: X X I wrote this X John> He wrote this X Jane> She originally wrote this") X X X(defvar sc-citation-leader "" X "*String used at the front of a composed citation.") X X(defvar sc-citation-delimiter ">" X "*String to use at the end of a composed citation. XThis string is used in both nested and non-nested citations. For best Xresults, use a single character with no trailing space.") X X(defvar sc-citation-separator " " X "*String used to separate the composed citation and the cited line. XNormally this character is a single space character though often a Xsingle tab character is used.") X X(defvar sc-default-author-name "Anonymous" X "*String used when author's name cannot be determined.") X X(defvar sc-default-attribution "Anon" X "*String used when author's attribution cannot be determined.") X X(defvar sc-cite-regexp "\\s *[a-zA-Z0-9]*\\s *>+\\s *" X "*Regular expression describing how a already cited line begins. XThe regexp is only used at the beginning of a line, so it doesn't need Xto start with a '^'.") X X(defvar sc-titlecue-regexp "\\s +-+\\s +" X "*Regular expression describing the separator between names and titles. XOften, people will set up their name field to look like this: X X (John Xavier Doe -- Computer Hacker Extraordinaire) X XTitle cue recognizes the ' -- ' as a separator between the name field Xand the title field. Set to nil to treat entire field as a name.") X X(defvar sc-confirm-always-p t X "*If t, always confirm attribution string before citing text body.") X X(defvar sc-preferred-attribution 'firstname X "*Specifies which part of the author's name becomes the attribution. XThe value of this variable should be a quoted symbol, based on the Xfollowing key: X X emailname -- email address name X initials -- initials of author X firstname -- first name of author X lastname -- last name of author X middlename1 -- first middle name of author X middlename2 -- second middle name of author X ... X XMiddle name indexes can be any positive integer greater than 0, though Xit is unlikely that many authors will supply more than one middle Xname, if that many.") X X(defvar sc-use-only-preference-p nil X "*Controls what happens when the preferred attribution cannot be found. XIf non-nil, then sc-default-attribution will be used if preferred Xattribution string can't be found. If nil, then some secondary scheme Xwill be employed to find a suitable attribution string.") X X(defvar sc-downcase-p nil X "*Non-nil means downcase the attribution and citation strings.") X X(defvar sc-rewrite-header-list X '((sc-no-header) X (sc-header-on-said) X (sc-header-inarticle-writes) X (sc-header-regarding-writes) X (sc-header-attributed-writes) X ) X "*List of reference header rewrite functions. XThe variable sc-preferred-header-style controls which function in this Xlist is chosen for automatic reference header insertions. Electric Xreference mode will cycle through this list of functions. Here's a Xlist of predefined reference header styles which you can use as a Xmodel for writing your own: X X sc-no-header: X {blank} X X sc-header-on-said [default]: X On X said: X X sc-header-inarticle-writes: X In article writes: X X sc-header-regarding-writes: X Regarding ; adds: X X sc-header-attributed-writes: X \"\" == writes: X XEach line of the reference will be prefixed by the string in Xsc-reference-tag-string. If you write your own reference header Xfunctions, you may want to use this variable. X XThe variables that you can use to create your headers are those that Xare included in sc-mail-fields-list. Some additional fields are Xalways made available by Supercite. These are: X X \"sc-author\" - author of the original article X \"sc-firstname\" - author's firstname X \"sc-lastname\" - author's lastname X \"sc-middlename-N\" - author's Nth middlename X \"sc-attribution\" - user chosen attribution string X \"sc-citation\" - user chosen citation string X \"from\" - the value of the \"From:\" field X XAny of these field names can be used (as strings) as arguments to Xsc-field.") X X(defvar sc-preferred-header-style 1 X "*Index into sc-rewrite-header-list specifying preferred header style. XSupercite uses this variable as an index into the header rewrite list Xto decide which style to use (by default) when writing the reference Xheader. Index zero accesses the first function in the list.") X X(defvar sc-electric-references-p t X "*Use electric references if non-nil.") X X(defvar sc-electric-circular-p t X "*Treat electric references as circular if non-nil.") X X(defvar sc-mail-fields-list X '("date" "message-id" "subject" "newsgroups" "references" X "from" "return-path" "path" "reply" "organization") X "*List of mail header whose values will be saved. XSupercite will scan the mail headers for the fields specified in this Xlist and save the values of these fields in sc-gal-information which Xcan be accessed with sc-field. You don't need to include the colon in Xthe field string.") X X(defvar sc-mumble-string "mumble" X "*Value returned by sc-field if chosen field cannot be found. XYou may want to set this to nil or add spaces around any string Xvalue.") X X(defvar sc-reference-tag-string ">>>>> " X "*String used at the beginning of default reference headers. XThis will visually separate a reference header from the cited body of Xtext, though the default is known to be annoying to some people.") X X(defvar sc-fill-paragraph-hook 'sc-fill-paragraph X "*Hook for filling a paragraph. XThis hook gets executed when you fill a paragraph either manually or Xautomagically. It expects point to be within the extent of the Xparagraph that is going to be filled.") X X(defvar sc-auto-fill-region-p nil X "*If non-nil, automatically fill each paragraph after it has been cited.") X X(defvar sc-fixup-whitespace-p nil X "*If non-nil, delete all leading white space before citing.") X X(defvar sc-nuke-mail-headers-p t X "*Nuke or don't nuke mail headers. XIf non-nil, nuke mail headers after gleaning useful information form Xthem. If nil, don't nuke mail headers.") X X(defvar sc-run-hook nil X "*User definable hook. XRuns after sc-cite-original executes.") X X(defvar sc-load-hook nil X "*User definable hook. XRuns after supercite is loaded. Set your customizations here.") X X X X;; ====================================================================== X;; keymaps X;; X(defvar sc-default-keymap X '(lambda () X (local-set-key "\C-c\C-r" 'sc-insert-reference) X (local-set-key "\C-c\C-t" 'sc-cite) X (local-set-key "\C-c\C-a" 'sc-recite) X (local-set-key "\C-c\C-u" 'sc-uncite) X (local-set-key "\C-c\C-i" 'sc-insert-citation) X (local-set-key "\C-c\C-o" 'sc-open-line) X (local-set-key "\C-c\C-q" 'sc-fill-paragraph-manually) X (local-set-key "\C-c\q" 'sc-fill-paragraph-manually) X (local-set-key "\C-c\C-m" 'sc-modify-information) X (local-set-key "\C-c\C-g" 'sc-glom-headers) X (local-set-key "\C-c\C-v" 'sc-version) X (local-set-key "\C-c?" 'sc-describe) X ) X "*Default keymap if major-mode can't be found in `sc-local-keymaps'.") X X(defvar sc-local-keymaps X '((mail-mode X (lambda () X (local-set-key "\C-c\C-r" 'sc-insert-reference) X (local-set-key "\C-c\C-t" 'sc-cite) X (local-set-key "\C-c\C-a" 'sc-recite) X (local-set-key "\C-c\C-u" 'sc-uncite) X (local-set-key "\C-c\C-i" 'sc-insert-citation) X (local-set-key "\C-c\C-o" 'sc-open-line) X (local-set-key "\C-c\C-q" 'sc-fill-paragraph-manually) X (local-set-key "\C-c\q" 'sc-fill-paragraph-manually) X (local-set-key "\C-c\C-m" 'sc-modify-information) X (local-set-key "\C-c\C-g" 'sc-glom-headers) X (local-set-key "\C-c\C-v" 'sc-version) X (local-set-key "\C-c?" 'sc-describe) X )) X (mh-letter-mode X (lambda () X (local-set-key "\C-c\C-r" 'sc-insert-reference) X (local-set-key "\C-c\C-t" 'sc-cite) X (local-set-key "\C-c\C-a" 'sc-recite) X (local-set-key "\C-c\C-u" 'sc-uncite) X (local-set-key "\C-ci" 'sc-insert-citation) X (local-set-key "\C-c\C-o" 'sc-open-line) X (local-set-key "\C-c\q" 'sc-fill-paragraph-manually) X (local-set-key "\C-c\C-m" 'sc-modify-information) X (local-set-key "\C-c\C-g" 'sc-glom-headers) X (local-set-key "\C-c\C-v" 'sc-version) X (local-set-key "\C-c?" 'sc-describe) X )) X (news-reply-mode mail-mode) X (vm-mail-mode mail-mode) X (e-reply-mode mail-mode) X (n-reply-mode mail-mode) X ) X "*List of keymaps to use with the associated major-mode.") X X X(defvar sc-electric-mode-map nil X "*Keymap for sc-electric-mode.") X X X(if sc-electric-mode-map X nil X (setq sc-electric-mode-map (make-sparse-keymap)) X (define-key sc-electric-mode-map "p" 'sc-eref-prev) X (define-key sc-electric-mode-map "n" 'sc-eref-next) X (define-key sc-electric-mode-map "s" 'sc-eref-setn) X (define-key sc-electric-mode-map "j" 'sc-eref-jump) X (define-key sc-electric-mode-map "\C-g" 'sc-eref-abort) X (define-key sc-electric-mode-map "x" 'sc-eref-abort) X (define-key sc-electric-mode-map "\r" 'sc-eref-exit) X (define-key sc-electric-mode-map "\n" 'sc-eref-exit) X (define-key sc-electric-mode-map "q" 'sc-eref-exit) X (define-key sc-electric-mode-map "g" 'sc-eref-goto) X (define-key sc-electric-mode-map "\C-hm" 'sc-eref-describe) X ) X X X;; ********************************************************************** X;; end of user defined variables X;; ********************************************************************** X X X;; ====================================================================== X;; global variables, not user accessable X;; X X(defconst sc-version-number "2.1") X X;; when rnewspost.el patch is installed (or function is overloaded) X;; this should be nil since supercite now does this itself. X(setq news-reply-header-hook nil) X X;; autoload for sc-electric-mode X(autoload 'sc-electric-mode "sc-electric" X "Major mode for viewing supercite reference headers." nil) X X X;; global alists, misc variables X;; X(make-variable-buffer-local 'sc-gal-attributions) X(make-variable-buffer-local 'sc-gal-information) X(make-variable-buffer-local 'sc-leached-keymap) X(make-variable-buffer-local 'sc-fill-arg) X X(setq-default sc-gal-attributions nil) X(setq-default sc-gal-information nil) X(setq-default sc-leached-keymap (current-local-map)) X(setq-default sc-fill-arg nil) X X;; the new citation style means we can clean out other headers in X;; addition to those previously cleaned out. anyway, we create our X;; own headers. cleans out mail, gnus, vm and other headers. add to X;; this for other mail or news readers you may be using. X X(setq sc-mail-yank-ignored-headers X (concat X "^via:\\|^origin:\\|^status:\\|^received:\\|^remailed\\|" X "^[a-z-]*message-id:\\|^\\(summary-\\)?line[s]?:\\|^cc:\\|" X "^subject:\\|^\\(\\(in-\\)?reply-\\)?to:\\|^sender:\\|^replied:\\|" X "^\\(\\(return\\|reply\\)-\\)?path:\\|^\\(posted-\\)?date:\\|" X "^\\(mail-\\)?from:\\|^newsgroup[s]?:\\|^organization:\\|^keywords:\\|" X "^distribution:\\|^xref:\\|^references:\\|^x-mailer:\\|" X "^\\(x-\\)?followup-to:\\|^x-vm-attributes:\\|^expires:\\|" X "^approved:\\|^apparently-to:\\|^summary:\\|" X "^x-vm-attributes:\\|^x-vm-v[0-9]+-data:")) X X X X X;; ====================================================================== X;; miscellaneous X X(defun sc-update-gal (attribution) X "Update the sc-gal-information alist. XAdd ATTRIBUTION and compose the nested and non-nested citation Xstrings." X (let ((attrib (if sc-downcase-p (downcase attribution) attribution))) X (aput 'sc-gal-information "sc-attribution" attrib) X (aput 'sc-gal-information "sc-nested-citation" X (concat attrib sc-citation-delimiter)) X (aput 'sc-gal-information "sc-citation" X (concat sc-citation-leader X attrib X sc-citation-delimiter X sc-citation-separator)))) X X X(defun sc-valid-index-p (index) X "Returns t if INDEX is a valid index into sc-rewrite-header-list. XDoes not check to see if function at index into list is a valid Xfunction without error." X (let ((last (1- (length sc-rewrite-header-list)))) X (and (natnump index) ;; a number, and greater than or equal to zero X (<= index last) ;; less than or equal to the last index X ))) X X X;; ====================================================================== X;; this section snarfs mail fields and places them in the info alist X X(defun sc-mail-yank-clear-headers (start end) X "Nuke mail headers between START and END. XUse sc-mail-yank-ignored-headers to determine which headers to nuke." X (save-excursion X (goto-char start) X (if (search-forward "\n\n" end t) X (save-restriction X (narrow-to-region start (point)) X (goto-char start) X (while (let ((case-fold-search t)) X (re-search-forward sc-mail-yank-ignored-headers nil t)) X (beginning-of-line) X (delete-region (point) X (progn (re-search-forward "\n[^ \t]") X (forward-char -1) X (point)))))))) X X X(defun sc-mail-fetch-field (field) X "Return the value of the header field FIELD. XThe buffer is expected to be narrowed to just the headers of the Xmessage." X (save-excursion X (goto-char (point-min)) X (let ((case-fold-search t) X (name (concat "^" (regexp-quote field) "[ \t]*:[ \t]*"))) X (goto-char (point-min)) X (if (re-search-forward name nil t) X (let ((opoint (point))) X (while (progn (forward-line 1) X (looking-at "[ \t]"))) X (buffer-substring opoint (1- (point)))))))) X X X(defun sc-fetch-fields (start end) X "Fetch the mail fields in the region from START to END. XAdd them to the global alist sc-gal-information. These fields can be Xaccessed in reference headers with sc-field." X (save-excursion X (save-restriction X (narrow-to-region start end) X (goto-char start) X (mapcar X (function X (lambda (field) X (let ((value (sc-mail-fetch-field field))) X (and value X (aput 'sc-gal-information field value))))) X sc-mail-fields-list) X (aput 'sc-gal-information "from" (sc-mail-fetch-field "from"))))) X X X(defun sc-field (field) X "Return the alist information associated with the FIELD. XIf FIELD is not a valid key in sc-gal-information, return Xsc-mumble-string." X (or (aget sc-gal-information field) X sc-mumble-string)) X X X;; ====================================================================== X;; contains supplied header reference rewrite functions X X(defun sc-no-header () X "Does nothing. Use this instead of nil to get a blank header." X ()) X X(defun sc-header-on-said () X "\"On , said:\"" X (insert sc-reference-tag-string X "On " (sc-field "date") ", " (sc-field "from") " said:\n")) X X(defun sc-header-inarticle-writes () X "\"In article , writes:\"" X (insert sc-reference-tag-string X "In article " (sc-field "message-id") X ", " (sc-field "from") " writes:\n")) X X(defun sc-header-regarding-writes () X "\"Regarding ; adds:\"" X (insert sc-reference-tag-string X "Regarding " (sc-field "subject") X "; " (sc-field "from") " adds:\n")) X X(defun sc-header-attributed-writes () X "\"\" == writes:" X (insert sc-reference-tag-string X "\"" (sc-field "sc-attribution") X "\" == " (sc-field "sc-author") " " X (sc-field "from") " writes:\n")) X X X;; ====================================================================== X;; this section queries the user for necessary information X;; X X(defun sc-query (default) X "Query for an attribution string with the DEFAULT choice. XReturns the string entered by the user, if non-empty and non-nil, or XDEFAULT otherwise." X (let* ((prompt (concat "Enter attribution string: (default " X default ") ")) X (query (read-string prompt))) X (if (or (null query) X (string= query "")) X default X query))) X X X(defun sc-confirm () X "Confirm the preferred attribution with the user. XWhen this function sc-gal-attributions should be set, and the aheadsym Xof this alist is used as the default selection. Also, X\\[keyboard-quit] selects the default." X (if (or sc-confirm-always-p X sc-force-confirmation-p) X (aput 'sc-gal-attributions X (let* ((default (aheadsym sc-gal-attributions)) X chosen X (prompt (concat "Complete " X (cond X ((eq sc-cite-context 'citing) "cite") X ((eq sc-cite-context 'reciting) "recite") X (t "")) X " attribution string: (default " X default ") ")) X (minibuffer-local-completion-map X (copy-keymap minibuffer-local-completion-map))) X (define-key minibuffer-local-completion-map "\C-g" X '(lambda () (interactive) (beep) (throw 'select-abort nil))) X (setq chosen (completing-read prompt sc-gal-attributions)) X (if (or (not chosen) X (string= chosen "")) X default X chosen) X )) X )) X X X;; ====================================================================== X;; this section contains primitive functions used in the email address X;; parsing schemes. they extract name fields from various parts of X;; the "from:" field. X X(defun sc-%-style-address (from-string) X "Extract the author's name from email address string FROM-STRING. XMatch addresses of the style \"name%[stuff].\"" X (and (string-match "[a-zA-Z0-9]+%" from-string 0) X (substring from-string (match-beginning 0) (1- (match-end 0))))) X X X(defun sc-@-style-address (from-string) X "Extract the author's name from email address string FROM-STRING. XMatch addresses of the style \"[stuff]name@[stuff].\"" X (and (string-match "[a-zA-Z0-9]+@" from-string 0) X (substring from-string (match-beginning 0) (1- (match-end 0))))) X X X(defun sc-!-style-address (from-string) X "Extract the author's name from email address string FROM-STRING. XMatch addresses of the style \"[stuff]![stuff]...!name[stuff].\"" X (let ((eostring (string-match "$" from-string 0)) X (mstart (string-match "![a-zA-Z0-9]+\\([^!a-zA-Z0-9]\\|$\\)" X from-string 0)) X (mend (match-end 0))) X (if mstart X (substring from-string (1+ mstart) (if (= mend eostring) X mend X (1- mend))) X nil))) X X X(defun sc-no-style-address (from-string) X "Extract the author's name from email address string FROM-STRING. XMatch addresses of the style \"name.\"" X (and (string-match "[a-zA-Z0-9]+" from-string 0) X (substring from-string (match-beginning 0) (match-end 0)))) X X X(defun sc-get-emailname (from-string) X "Get an email address from the FROM-STRING." X (cond X ((sc-%-style-address from-string)) X ((sc-@-style-address from-string)) X ((sc-!-style-address from-string)) X ((sc-no-style-address from-string)) X (t (substring from-string 0 10)))) X X X;; ====================================================================== X;; this section contains functions that will extract a list of names X;; from the name field string. X X X(defun sc-string-car (namestring) X "Return the string-equivalent \"car\" of NAMESTRING. X X example: (sc-string-car \"John Xavier Doe\") X => \"John\"" X (substring namestring X (progn (string-match "\\s *" namestring) (match-end 0)) X (progn (string-match "\\s *\\S +" namestring) (match-end 0)))) X X X(defun sc-string-cdr (namestring) X "Return the string-equivalent \"cdr\" of NAMESTRING. X X example: (sc-string-cdr \"John Xavier Doe\") X => \"Xavier Doe\"" X (substring namestring X (progn (string-match "\\s *\\S +\\s *" namestring) X (match-end 0)))) X X X(defun sc-extract-namestring (from-string) X "Extract the name string from the FROM-STRING. XThis should be the author's full name minus an optional title." X (let ((pstart (string-match "(.*)" from-string 0)) X (pend (match-end 0)) X (qstart (string-match "\".*\"" from-string 0)) X (qend (match-end 0)) X (bstart (string-match "\\([.a-zA-Z0-9---]+\\s *\\)+" from-string 0)) X (bend (match-end 0))) X (cond X (pstart (substring from-string X (1+ pstart) X (or (string-match sc-titlecue-regexp X from-string X (1+ pstart)) X (1- pend)))) X (qstart (substring from-string X (1+ qstart) X (or (string-match sc-titlecue-regexp X from-string X (1+ qstart)) X (1- qend)))) X (bstart (substring from-string X bstart X (or (string-match sc-titlecue-regexp X from-string X bstart) X bend)))))) X X X(defun sc-namestring-to-list (namestring) X "Convert NAMESTRING to a list of names. X X example: (sc-namestring-to-list \"John Xavier Doe\") X => (\"John\" \"Xavier\" \"Doe\")" X (if (not (string-match namestring "")) X (append (list (sc-string-car namestring)) X (sc-namestring-to-list (sc-string-cdr namestring))))) X X X(defun sc-strip-initials (namelist) X "Extract the author's initials from the NAMELIST." X (if (not namelist) X nil X (concat (substring (car namelist) 0 1) X (sc-strip-initials (cdr namelist))))) X X X;; ====================================================================== X;; this section handles selection of the attribution and citation strings X;; X X(defun sc-populate-alists (from-string) X "Put important and useful information in the alists. XAlists are sc-gal-information and sc-gal-attributions. Return the list Xof name symbols." X (let* ((namelist (sc-namestring-to-list (sc-extract-namestring from-string))) X (revnames (reverse (cdr namelist))) X (midnames (reverse (cdr revnames))) X (firstname (car namelist)) X (midnames (reverse (cdr revnames))) X (lastname (car revnames)) X (initials (sc-strip-initials namelist)) X (emailname (sc-get-emailname from-string)) X (n 1) X (symlist '(emailname initials firstname lastname))) X X ;; put basic information X (aput 'sc-gal-attributions 'firstname firstname) X (aput 'sc-gal-attributions 'lastname lastname) X (aput 'sc-gal-attributions 'emailname emailname) X (aput 'sc-gal-attributions 'initials initials) X X (aput 'sc-gal-information "sc-firstname" firstname) X (aput 'sc-gal-information "sc-lastname" lastname) X (aput 'sc-gal-information "sc-emailname" emailname) X (aput 'sc-gal-information "sc-initials" initials) X X ;; put middle names X (mapcar X (function X (lambda (name) X (let ((symbol (intern (format "middlename%d" n))) X (string (format "sc-middlename-%d" n))) X (aput 'sc-gal-attributions symbol name) X (aput 'sc-gal-information string name) X (setq n (1+ n)) X (nconc symlist (list symbol))))) X midnames) X X ;; build the sc-author entry X (aput 'sc-gal-information "sc-author" X (concat firstname " " (mapconcat X (function X (lambda (name) name)) X midnames " ") X (if midnames " ") lastname)) X symlist)) X X X(defun sc-sort-attribution-alist () X "Put preferred attribution at head of sc-gal-attributions alist." X (asort 'sc-gal-attributions sc-preferred-attribution) X X ;; use backup scheme if preference is not legal X (if (or (null sc-preferred-attribution) X (anot-head-p sc-gal-attributions sc-preferred-attribution) X (let ((prefval (aget sc-gal-attributions X sc-preferred-attribution))) X (or (null prefval) X (string= prefval "")))) X ;; no legal attribution X (if sc-use-only-preference-p X (aput 'sc-gal-attributions 'sc-user-query X (sc-query sc-default-attribution)) X ;; else use secondary scheme X (asort 'sc-gal-attributions 'firstname)))) X X X(defun sc-build-attribution-alist (from-string) X "Extract attributions from FROM-LIST, applying preferences." X (let ((symlist (sc-populate-alists from-string)) X (headval (progn (sc-sort-attribution-alist) X (aget sc-gal-attributions X (aheadsym sc-gal-attributions))))) X X ;; foreach element in the symlist, remove the corresponding key-value X ;; pair in the alist, then insert just the value. X (mapcar X (function X (lambda (symbol) X (let ((value (aget sc-gal-attributions symbol))) X (if (not (or (null value) X (string= value ""))) X (aput 'sc-gal-attributions value)) X (adelete 'sc-gal-attributions symbol)))) X symlist) X X ;; now reinsert the head (preferred) attribution, this effectively X ;; just moves the head value to the front of the list. X (aput 'sc-gal-attributions headval) X X ;; check to be sure alist is not nil X (if (null sc-gal-attributions) X (aput 'sc-gal-attributions sc-default-attribution)))) X X X(defun sc-select () X "Select an attribution and create a citation string." X (cond X (sc-nested-citation-p X (sc-update-gal "")) X ((null (aget sc-gal-information "from" t)) X (aput 'sc-gal-information "sc-author" sc-default-author-name) X (sc-update-gal (sc-query sc-default-attribution))) X ((null sc-gal-attributions) X (sc-build-attribution-alist (aget sc-gal-information "from" t)) X (sc-confirm) X (sc-update-gal (aheadsym sc-gal-attributions))) X (t X (sc-confirm) X (sc-update-gal (aheadsym sc-gal-attributions))) X ) X t) X X X;; ====================================================================== X;; region citing and unciting X X(defun sc-cite-region (start end) X "Cite a region delineated by START and END." X (save-excursion X (set-mark end) X (goto-char start) X (beginning-of-line) X (let ((fstart (point)) X (fend (point))) X (while (< (point) (mark)) X ;; remove leading whitespace if desired X (and sc-fixup-whitespace-p X (fixup-whitespace)) X ;; if end of line then perhaps autofill X (cond ((eolp) X (or (= fstart fend) X (not sc-auto-fill-region-p) X (save-excursion (set-mark fend) X (goto-char (/ (+ fstart fend 1) 2)) X (run-hooks 'sc-fill-paragraph-hook))) X (setq fstart (point) X fend (point))) X ;; not end of line so perhap cite it X ((not (looking-at sc-cite-regexp)) X (insert (aget sc-gal-information "sc-citation"))) X (sc-nested-citation-p X (insert (aget sc-gal-information "sc-nested-citation")))) X (setq fend (point)) X (forward-line 1))))) X X X(defun sc-uncite-region (start end cite-regexp) X "Uncite a previously cited region delineated by START and END. XCITE-REGEXP describes how a cited line of texts starts. Unciting also Xauto-fills paragraph if sc-auto-fill-region-p is non-nil." X (save-excursion X (set-mark end) X (goto-char start) X (beginning-of-line) X (let ((fstart (point)) X (fend (point))) X (while (< (point) (mark)) X ;; if end of line, then perhaps autofill X (cond ((eolp) X (or (= fstart fend) X (not sc-auto-fill-region-p) X (save-excursion (set-mark fend) X (goto-char (/ (+ fstart fend 1) 2)) X (run-hooks 'sc-fill-paragraph-hook))) X (setq fstart (point) X fend (point))) X ;; not end of line so perhaps uncite it X ((looking-at cite-regexp) X (save-excursion X (save-restriction X (narrow-to-region (progn (beginning-of-line) X (point)) X (progn (end-of-line) X (point))) X (beginning-of-line) X (delete-region (point-min) X (progn (re-search-forward cite-regexp X (point-max) X t) X (match-end 0))))))) X (setq fend (point)) X (forward-line 1))))) X X X;; ====================================================================== X;; this section contains paragraph filling support X X(defun sc-guess-fill-prefix () X "Guess the fill prefix used on the current line. XUse various heuristics to find the fill prefix. Search begins on first Xnon-blank line in the region delineated by point and mark. X X 1) If fill-prefix is already bound to the empty string, return X nil. X X 2) If fill-prefix is already bound, but not to the empty X string, return the value of fill-prefix. X X 3) If the current line starts with the last chosen citation X string, then that string is returned. X X 4) If the current line starts with a string matching the regular X expression, sc-cite-regexp, then that string is returned. X X 5) Nil is returned." X (save-excursion X ;; scan for first non-blank line in the region X (beginning-of-line) X (while (and (< (point) (mark)) X (eolp)) X (forward-line 1)) X (let ((citation (aget sc-gal-information "sc-citation"))) X (cond X ((string= fill-prefix "") nil) X (fill-prefix) X ((looking-at (regexp-quote citation)) citation) X ((looking-at sc-cite-regexp) X (buffer-substring X (point) (progn X (re-search-forward (concat sc-cite-regexp "\\s *") X (point-max) nil) X (point)))) X ((looking-at (concat ".*" sc-citation-delimiter "\\s *")) X (buffer-substring X (point) (progn (re-search-forward (concat ".*" sc-citation-delimiter X "\\s *")) X (point)))) X (t nil))))) X X X(defun sc-consistant-cite-p (prefix) X "Check current paragraph for consistant citation. XScans to paragraph delineated by (forward|backward)-paragraph to see Xif all lines start with PREFIX. Returns t if entire paragraph is Xconsistantly cited, nil otherwise." X (save-excursion X (let ((end (progn (forward-paragraph) X (beginning-of-line) X (or (not (eolp)) X (forward-char -1)) X (point))) X (start (progn (backward-paragraph) X (beginning-of-line) X (or (not (eolp)) X (forward-char 1)) X (point))) X (badline t)) X (goto-char start) X (beginning-of-line) X (while (and (< (point) end) X badline) X (setq badline (looking-at prefix)) X (forward-line 1)) X badline))) X X X(defun sc-fill-start (fill-prefix) X "Find buffer position of start of region which begins with FILL-PREFIX. XRestrict scan to current paragraph." X (save-excursion X (let ((badline nil) X (top (save-excursion X (backward-paragraph) X (beginning-of-line) X (or (not (eolp)) X (forward-char 1)) X (point)))) X (while (and (not badline) X (> (point) top)) X (forward-line -1) X (setq badline (not (looking-at fill-prefix))))) X (forward-line 1) X (point))) X X X(defun sc-fill-end (fill-prefix) X "Find the buffer position of end of region which begins with FILL-PREFIX. XRestrict scan to current paragraph." X (save-excursion X (let ((badline nil) X (bot (save-excursion X (forward-paragraph) X (beginning-of-line) X (or (not (eolp)) X (forward-char -1)) X (point)))) X (while (and (not badline) X (< (point) bot)) X (beginning-of-line) X (setq badline (not (looking-at fill-prefix))) X (forward-line 1))) X (forward-line -1) X (point))) X X X(defun sc-fill-paragraph () X "Supercite's paragraph fill function. XFill the paragraph containing or following point. Use Xsc-guess-fill-prefix to find the fill-prefix for the paragraph. X XIf the paragraph is inconsistantly cited (mixed fill-prefix), then the Xuser is queried to restrict the the fill to only those lines around Xpoint which begin with the fill prefix. X XThe variable sc-fill-arg is passed to fill-paragraph and Xfill-region-as-paragraph which controls justification of the Xparagraph. sc-fill-arg is set by sc-fill-paragraph-manually." X (save-excursion X (let ((pnt (point)) X (fill-prefix (sc-guess-fill-prefix))) X (cond X ((not fill-prefix) X (fill-paragraph sc-fill-arg)) X ((sc-consistant-cite-p fill-prefix) X (fill-paragraph sc-fill-arg)) X ((y-or-n-p "Inconsistent citation found. Restrict? ") X (message "") X (fill-region-as-paragraph (progn (goto-char pnt) X (sc-fill-start fill-prefix)) X (progn (goto-char pnt) X (sc-fill-end fill-prefix)) X sc-fill-arg)) X (t X (message "") X (progn X (setq fill-prefix (aget sc-gal-information "sc-citation")) X (fill-paragraph sc-fill-arg))))))) X X X X;; ====================================================================== X;; the following functions are the top level, interactive functions that X;; can be bound to key strokes X X(defun sc-insert-reference (arg) X "Insert, at point, a reference header in the body of the reply. XNumeric ARG indicates which header style from sc-rewrite-header-list Xto use when rewriting the header. No supplied ARG indicates use of Xsc-preferred-header-style. X XWith just \\[universal-argument], electric reference insert mode is Xentered, regardless of the value of sc-electric-references-p. See Xsc-electric-mode for more information. With numeric ARG, if Xsc-electric-references-p is non-nil, then electric reference insert Xmode is entered, otherwise, the selected header style is simply Xinserted." X (interactive "P") X (if (consp arg) X (sc-electric-mode) X (let ((pref (cond ((sc-valid-index-p arg) arg) X ((sc-valid-index-p sc-preferred-header-style) X sc-preferred-header-style) X (t 0)))) X (if sc-electric-references-p (sc-electric-mode pref) X (condition-case err X (eval (nth pref sc-rewrite-header-list)) X (void-function X (progn (message X "Symbol's function definition is void: %s. (Header %d)." X (symbol-name (car (cdr err))) X pref) X (beep))) X (error X (progn (message "Error evaluating rewrite header function %d." X pref) X (beep))) X )) X ))) X X X(defun sc-cite (arg) X "Cite the region of text between point and mark. XNumeric ARG, if supplied, is passed unaltered to sc-insert-reference. X XThe mail header lines should be at the top of the region, with the Xbody of the reply following. These mail header lines will be parse Xfirst for useful information, then deleted." X (interactive "P") X (catch 'select-abort X (let ((sc-cite-context 'citing) X (sc-force-confirmation-p (interactive-p))) X (sc-select) X (undo-boundary) X (let ((xchange (if (> (mark) (point)) nil X (exchange-point-and-mark) X t))) X (sc-insert-reference arg) X (sc-cite-region (point) (mark)) X ;; leave point on first cited line X (while (and (< (point) (mark)) X (not (looking-at (aget sc-gal-information X (if sc-nested-citation-p X "sc-nested-citation" X "sc-citation"))))) X (forward-line 1)) X (and xchange X (exchange-point-and-mark)) X ) X ))) X X X X(defun sc-uncite () X "Uncite the region between point and mark." X (interactive) X (undo-boundary) X (let ((xchange (if (> (mark) (point)) nil X (exchange-point-and-mark) X t)) X (fp (or (sc-guess-fill-prefix) X ""))) X (sc-uncite-region (point) (mark) (regexp-quote fp)) X (and xchange X (exchange-point-and-mark)))) X X X(defun sc-recite () X "Recite the region by first unciting then citing the text." X (interactive) X (catch 'select-abort X (let ((sc-cite-context 'reciting) X (sc-force-confirmation-p t)) X (sc-select) X (undo-boundary) X (let ((xchange (if (> (mark) (point)) nil X (exchange-point-and-mark) X t))) X (sc-uncite-region (point) (mark) (regexp-quote (sc-guess-fill-prefix))) X (sc-cite-region (point) (mark)) X (and xchange X (exchange-point-and-mark)) X ) X ))) X X X(defun sc-insert-citation () X "Insert citation string at beginning of current line." X (interactive) X (save-excursion X (beginning-of-line) X (insert (aget sc-gal-information "sc-citation")))) X X X(defun sc-open-line (arg) X "Insert a newline and leave point before it. XAlso inserts the guessed prefix at the beginning of the new line. With Xnumeric ARG, inserts that many newlines." X (interactive "p") X (save-excursion X (let ((start (point)) X (string (sc-guess-fill-prefix))) X (open-line arg) X (goto-char start) X (forward-line 1) X (while (< 0 arg) X (insert string) X (forward-line 1) X (setq arg (- arg 1)))))) X X X(defun sc-fill-paragraph-manually (arg) X "Fill current cited paragraph. XReally just runs the hook sc-fill-paragraph-hook, however it does set Xthe global variable sc-fill-arg to the value of ARG. This is Xcurrently the only way to pass an argument to a hookified function." X (interactive "P") X (setq sc-fill-arg arg) X (run-hooks 'sc-fill-paragraph-hook)) X X X(defun sc-modify-information (arg) X "Interactively modify information in sc-gal-information. X\\[universal-argument] if supplied, deletes the entry from the alist. XYou can add an entry by supplying a key instead of completing." X (interactive "P") X (let* ((delete-p (consp arg)) X (action (if delete-p "delete" "modify")) X (defaultkey (aheadsym sc-gal-information)) X (prompt (concat "Select information key to " X action ": (default " X defaultkey ") ")) X (key (completing-read prompt sc-gal-information)) X ) X (if (or (string= key "") X (null key)) X (setq key defaultkey)) X (if delete-p (adelete 'sc-gal-information key) X (let* ((oldval (aget sc-gal-information key t)) X (prompt (concat "Enter new value for key \"" X key "\" (default \"" oldval "\") ")) X (newval (read-input prompt))) X (if (or (string= newval "") X (null newval)) X nil X (aput 'sc-gal-information key newval) X ))) X )) X X X(defun sc-glom-headers () X "Glom information from mail headers in region between point and mark. XAny old attribution information is lost." X (interactive) X (setq sc-gal-attributions nil) X (setq sc-gal-information nil) X (let ((start (region-beginning)) X (end (region-end)) X (sc-force-confirmation-p t) X (sc-cite-context nil)) X (sc-fetch-fields start end) X (if sc-nuke-mail-headers-p X (sc-mail-yank-clear-headers start end)) X (sc-select))) X X X(defun sc-version () X "Show supercite version." X (interactive) X (message "Using Supercite %s" sc-version-number)) X X X X;; ====================================================================== X;; leach onto current mode X X(defun sc-append-current-keymap () X "Append some useful key bindings to the current local key map. XThis searches sc-local-keymap for the keymap to install based on the Xmajor-mode of the current buffer." X (let ((hook (car (cdr (assq major-mode sc-local-keymaps))))) X (cond X ((not hook) X (run-hooks 'sc-default-keymap)) X ((not (listp hook)) X (setq hook (car (cdr (assq hook sc-local-keymaps)))) X (run-hooks 'hook)) X (t X (run-hooks 'hook)))) X (setq sc-leached-keymap (current-local-map))) X X X(defun sc-snag-all-keybindings () X "Snag all keybindings in major-modes current keymap." X (let* ((curkeymap (current-local-map)) X (symregexp ".*sc-.*\n") X (docstring (substitute-command-keys "\\{curkeymap}")) X (start 0) X (maxend (length docstring)) X (spooge "")) X (while (and (< start maxend) X (string-match symregexp docstring start)) X (setq spooge (concat spooge (substring docstring X (match-beginning 0) X (match-end 0)))) X (setq start (match-end 0))) X spooge)) X X X(defun sc-spoogify-docstring () X "Modifies (makes into spooge) the docstring for the current major mode. XThis will leach the keybinding descriptions for supercite onto the end Xof the current major mode's docstring. If major mode is preloaded, Xthis function will first make a copy of the list associated with the Xmode, then modify this copy." X (let* ((symfunc (symbol-function major-mode)) X (doc-cdr (nthcdr 2 symfunc)) X (doc-str (documentation major-mode))) X (cond X ;; is a docstring even provided? X ((not (stringp doc-str))) X ;; have we already leached on? X ((string-match "Supercite" doc-str)) X ;; lets build the new doc string X (t X (let ((newdoc-str (concat doc-str " X XThe major mode for this buffer has been modified to include the XSupercite 2.1 package for handling attributions and citations of Xoriginal messages in email replies. For more information on this Xpackage, type \"\\[sc-describe]\" (see below). The following keys are Xbound to Supercite commands: X X" X (sc-snag-all-keybindings)))) X (condition-case nil X (setcar doc-cdr newdoc-str) X (error X ;; the major mode must be preloaded, make a copy first X (setq symfunc (copy-sequence (symbol-function major-mode)) X doc-cdr (nthcdr 2 symfunc)) X (setcar doc-cdr newdoc-str) X (fset major-mode symfunc) X )) X )) X ))) X X X;; ====================================================================== X;; this section contains default hooks and hook support for execution X X(defun sc-cite-original () X "Hook version of sc-cite. X XThis is callable from the various mail and news readers' reply Xfunction according to the predefined standard. Type X\"\\[sc-describe]\" for more details. Sc-cite-original does not do Xany yanking of the original message but it does require a few things: X X 1) The reply buffer is the current buffer. X X 2) The original message has been yanked and inserted into the X reply buffer. X X 3) Verbose mail headers from the original message have been X inserted into the reply buffer directly before the text of the X original message. X X 4) Point is at the beginning of the verbose headers. X X 5) Mark is at the end of the body of text to be cited." X (setq sc-gal-attributions nil) X (setq sc-gal-information nil) X (let ((start (region-beginning)) X (end (region-end)) X (sc-electric-references-p nil)) X (sc-fetch-fields start end) X (if sc-nuke-mail-headers-p X (sc-mail-yank-clear-headers start end)) X (sc-cite sc-preferred-header-style) X (sc-append-current-keymap) X (sc-spoogify-docstring) X (run-hooks 'sc-run-hook) X )) X X X X;; ====================================================================== X;; describe this package X;; X X(defun sc-describe () X "Describe the Supercite 2.1 package. X XThis package provides mechanisms for doing sophisticated citing of Xyanked text in the reply buffers of the major news and email reading Xmodes. X XSupercite 2.1 has been tested and *seems* to work with GNUS 3.12-3.13 XRMAIL 18.55 and VM 4.37-4.41. It is also supposed to work with MH-E Xmode and perhaps even GNEWS, RNEWS, PCMAIL and other packages. Some Xmodifications may be necessary to run supercite with these packages. XSee the accompanying README file for details on how to link up with Xsupercite. X XAuthor: X XNAME: Barry A. Warsaw USMAIL: National Institute of XTELE: (301) 975-3460 Standards and Technology XUUCP: uunet!cme.nist.gov!warsaw Rm. B-124, Bldg. 220 XINET: warsaw@cme.nist.gov Gaithersburg, MD 20899 X XGet on the Supercite mailing list: X XSend articles to: X INET: supercite@cme.nist.gov X UUCP: uunet!cme.nist.gov!supercite X XSend administrivia (additions/deletions to list, etc) to: X INET: supercite-request@cme.nist.gov X UUCP: uunet!cme.nist.gov!supercite-request X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XWhat is a citation? A \"citation\" is the acknowledgment of the Xoriginal author of a mail message, in the body of the reply. The X\"attribution string\" is the part of the author's name that will be Xused to cite the body of the text (e.g. \"John\", the author's first Xname). The \"citation string\" is built from the \"citation leader\", Xthe attribution string, the \"citation delimiter\", and the \"citation Xseparator\". It is the string that is inserted in front of every line Xto be cited in the reply body (e.g. \"John> \"). X XThere are two general forms of citation. In \"nested citations\", Xindication is made that the cited line was written by someone *other* Xthan the current message author, but no reference is made as to the Xidentity of the original author. Here's an example of what a message Xbuffer would look like using nested citations after multiple replies: X X >> John originally wrote this X >> and this as well X > Jane said that John didn't know X > what he was talking about X And that's what I think too. X XIn \"non-nested citations\" each cited line begins with an informative Xstring referencing the original author. Only the first level of Xreferencing will be shown; subsequent citations don't nest the Xreferences. The same message described above might look like this if Xnon-nested citations were used: X X John> John originally wrote this X John> and this as well X Jane> Jane said that John didn't know X Jane> what he was talking about X And that's what I think too. X XNotice that my inclusion of Jane's inclusion of John's original Xmessage did not result in a cited line beginning with: \"Jane>John>\". XThus no nested citations. X XHeuristics are used to extract such information as the author's name Xand email address from the mail headers in the reply buffer. This Xinformation is made available to the supercite user for use in Xbuilding the citation string and reference header. The \"reference Xheader\" is header placed at the top of the cited body of text Xdescribing who the author is in more detail. X XThe citing of the text body is undoable, so the user could yank and Xcite the text, undo, then continually re-cite the text until the Xdesired citation string is inserted. Often people would like a Xnickname to be used as the citation string, but this nickname cannot Xbe picked up by supercite. It is a simple matter to undo the original Xcitation, and then perform a citation with the nickname as the Xattribution string. X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XThere are a number of variables which control some of the features Xdescribed thus far. First there is the variable which controls whether Xnested or non-nested citations will be used: X X Variable: sc-nested-citation-p X Controls citation style. If nil, non-nested citations are X used. If non-nil, old-style nested citations are used. X Default: nil. X XFor non-nested citations, the citation string is made up of four Xparts, the citation leader, the attribution string, the citation Xdelimiter and the citation separator. The attribution string is Xdetermined by supercite (though you can override this -- see below); Xthe other three parts are user defined. Nested citations use only the Xcitation separator: X X Variable: sc-citation-leader X String that leads the composed citation string. X Default: \" \". X X Variable: sc-citation-delimiter X String that indicates a line has been cited. For nested X citations this string is inserted in front of all cited X lines. For non-nested citations, this string is inserted X after the attribution string but before the citation X separator. Default: \">\". X X Variable: sc-citation-separator X String that ends a composed citation string. Placed between X the citation delimiter and the original line of text. X XFor example, say the following preferences are in use: X X (setq sc-citation-leader \" \") X (setq sc-citation-delimiter \">\") X (setq sc-citation-separator \" \") X Xand the attribution string was \"Jane\". The composed citation string Xwould be \" Jane> \", which would be used in non-nested citations. XOf course, only \">\" would be used in nested citations. X XOccasionally, for whatever reason, the author's name cannot be found Xin the mail header, and so a default author name may be used: X X Variable: sc-default-author-name X String used when author's name cannot be found. X Default: \"Anonymous\". X XAlso if the author's name cannot be found, a default attribution Xstring may be used, from which a legal citation string will be built: X X Variable: sc-default-attribution X String used when author's attribution string cannot be X found. Default: \"Anon\". X XFinally, how does the package determine if a line has already been Xcited, so that for non-nested citations, the line won't be recited? XThis is accomplished through the use of a regular expression: X X Variable: sc-cite-regexp X Regular expression that describes how an already cited line X begins. Default: \"\\\\s *[a-zA-Z0-9]*\\\\s *>+\\\\s *\". X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XSupercite employs a number of heuristics to decipher the author's name Xbased on the \"From:\" field which is usually present in all mail and Xnews reading buffers. If possible, it will pick out the author's Xfirst, last and middle names, the author's initials and the author's Xemail terminus. Supercite can recognize \"From:\" lines with the Xfollowing forms: X X From: John Xavier Doe X From: \"John Xavier Doe\" X From: doe@speedy.computer.com (John Xavier Doe) X From: computer!speedy!doe (John Xavier Doe) X From: doe%speedy@computer.com (John Xavier Doe) X From: computer!speedy!doe (John Xavier-Doe) X From: computer!speedy!doe (John Xavier-Doe -- Decent Hacker) X XOnce supercite has parsed this field, it puts together a list of these Xnames and may present them to the user for selection. X XNote that some author fields (as in the last example above) will Xcontain a descriptive title. The user can choose to ignore the title, Xwhile still recognizing hyphenated names, through the use of a regular Xexpression: X X Variable: sc-titlecue-regexp X Regular expression that delineates names from titles in the X author's name fields. Default: \"\\\\s +-+\\\\s +\". X XOnce an attribution string is extracted, supercite will normally Xuse it to build the citation string automatically. However, you can Xtell supercite to request confirmation of the selected attribution Xbefore the citation string is built: X X Variable: sc-confirm-always-p X If non-nil, always confirm attribution string with user X before using to cite text. If nil, use automatic selection X to choose attribution string. Default: t. X XIf you choose to confirm the attribution before the citation string is Xbuilt, you will be presented with a list of choices. Supercite Xmaintains a notion of your \"preferred\" attribution string and this Xis presented as the default choice. Hitting the carriage return will Xselect this preferred default. You are free to type in any string at Xthe prompt, even if it is not one of the presented choices, and this Xstring becomes the literal attribution string when you hit return. XWhen an attribution string is confirmed, or typed in, it now becomes Xthe preferred default attribution string for future insertions. X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XYou can tell supercite which part of the author's name is your Xpreference for use as the attribution string: X X Variable: sc-preferred-attribution X Quoted symbol specifying which portion of an author's name X should be used when building the attribution string using X the following key: X X emailname -- email terminus X initials -- author's initials X firstname -- first name X lastname -- last name X middlename1 -- first middle name X middlename2 -- second middle name X ... X X Middlename indexes can be any positive integer greater than X 0, though it is unlikely that many authors will supply more X than one middle name, if that many. Default: 'firstname. X XIf you are using automatic selection, and your preferred attribution Xcan't be found (i.e. is either nil, or the empty string), then a Xsecondary method can be employed to find a valid attribution string. XA variable controls whether a secondary method will be used in this Xcase, or whether supercite should just use the default attribution (in Xsc-default-attribution): X X Variable: sc-use-only-preference-p X Controls what happens when the preferred attribution string X cannot be found. If non-nil, then sc-default-attribution is X used, otherwise a secondary scheme is employed. X Default: nil. X XThe following steps are taken to find a valid attribution string when Xsc-use-only-preference-p is nil. The first step to return a non-nil, Xnon-empty string becomes the attribution. X X 1. Use the author's first name. X 2. Find the first non-nil, non-empty attribution string in the X attribution list. X 3. If sc-confirm-always-p is non-nil, then the user is queried X for an attribution, otherwise, X 4. sc-default-attribution is used. X XOnce a legal attribution string is found, you can force the string to Xlower case characters. X X Variable: sc-downcase-p X Non-nil means downcase the attribution string. X Default: nil. X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XTypically, citing is performed on a body of text that has been yanked Xfrom a mail or news reading buffer. This yanked text should have the Xverbose headers at the top of the region to be cited. As mentioned Xabove, Supercite will parse these headers, picking out useful Xinformation (most notably the \"From:\" line), then delete those mail Xheaders, and replace them in the reply buffer with user customizable Xreference headers. You can have multiple references header styles at Xyour disposal and can customize your own headers, adding them to the Xlist of those available. This list is kept in the variable: X X Variable: sc-rewrite-header-list X List of user customizable reference header rewrite X functions. X Default: '((sc-no-header) X (sc-header-on-said) X (sc-header-inarticle-writes) X (sc-header-regarding-writes) X (sc-header-attributed-writes)). X XAdd your own functions to this list or re-order the list to utilize Xyour own custom reference headers. A reference header is rewritten Xautomatically when the text is originally yanked, and a command is Xprovided that allows the user to insert any reference header in the Xlist. The header written by default is user customizable: X X Variable: sc-preferred-header-style X Integer specifying which header rewrite function is used X when automatically inserting the rewritten header. This is X an index into sc-rewrite-header-list, with the first element X indexed as zero. Default: 1. X XAlternatively, you can use \"electric reference\" inserting to select Xa reference header to use. In electric reference insert mode, you are Xplaced in a recursive edit where you can scan back and forth through Xthe list of headers. You can also set a new preferred header style. XElectric reference inserting is also available through the Xsc-insert-reference command (see below). This variable controls Xwhether you will automatically insert references, or use electric Xreference mode: X X Variable: sc-electric-references-p X Non-nil specifies use electric reference insert mode. X Default: t. X XWhile in electric reference mode, certain keys are bound to certain Xfunctions. All other keys, except those which self insert, are still Xvalid. Self inserting keys are reinstated when you exit electric Xreference insert mode. Here are the default keybindings in this mode: X\\{sc-electric-mode-map} X XYou cannot edit the references while in electric reference mode. XAlso, there is a variable which controls whether the rewrite functions Xlist should be treated as circular in electric reference mode: X X Variable: sc-electric-circular-p X If non-nil, treat the reference header rewrite list of X functions as circular in electric reference mode. X Default: t. X XYou may want to include some information about the author in your Xcustom reference headers. This information can come from the mail Xheaders or some internal supercite variables. There is a variable Xthat describes which mail headers should be fetched and remembered for Xuse in the reference headers: X X Variable: sc-mail-fields-list X List of mail header fields that you want supercite to X extract and remember. These can be accessed through the X sc-field function in your reference header functions. X Default: '(\"date\" \"message-id\" \"subject\" \"newsgroups\" X \"references\" \"return-path\" \"path\" \"reply\" X \"organization\") X XIn addition, supercite always provides the following information Xfields: X X 1. \"sc-attribution\" (the selected attribution string) X 2. \"sc-nested-citation\" (the nested citation string) X 3. \"sc-citation\" (the non-nested citation string) X 4. \"from\" (the From: mail header) X 5. \"sc-author\" (the author's full name) X 6. \"sc-firstname\" (the author's first name) X 7. \"sc-lastname\" (the author's last name) X 8. \"sc-middlename-1\" (the author's first middle name) X 9. ... (more middle names) X XIf you access a field with sc-field that does not exist in the Xinformation list, supercite will return a mumble string: X X Variable: sc-mumble-string X String returned by sc-field if chosen field can't be found. X Default: \"mumble\". X XAfter supercite has gleaned useful information from the mail headers, Xit will usually remove them from the reply buffer. You can tell Xsupercite to remove the headers or leave them in the buffer: X X Variable: sc-nuke-mail-headers-p X If non-nil, nuke the mail headers, otherwise leave them in X the reply buffer. X Default: t. X XThe default reference header rewrite functions typically insert a Xstring which serves to visually separate the header from the cited Xbody of text. You may want to change this for the default functions, Xor use it in your custom header rewrite functions: X X Variable: sc-reference-tag-string X String that is inserted before reference header lines on X those reference rewrite functions which are predefined. X Default: \">>>>> \" X X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XSupercite provides a paragraph filling function which recognizes the Xcitation string to properly fill a cited text body. There are other Xpackages freely available which also work quite well when filling such Xa prefixed paragraph, and so supercite calls the filling function via Xa hook: X X Variable: sc-fill-paragraph-hook X Hook for filling a paragraph. run when you fill a paragraph X either automatically or manually. X Default: 'sc-fill-paragraph. X XEach cited paragraph can be automatically filled when cited: X X Variable: sc-auto-fill-region-p X If non-nil, automatically fill each paragraph after it has X been cited. Default: nil. X XThere is a function available to manually fill a paragraph if you Xdon't want automatic filling (see below). X X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XHere are a couple of other user definable variables. For more Xinformation on these or any supercite variable, type: X\\[describe-variable] . X X Variable: sc-fixup-whitespace-p X If non-nil, delete all leading white space before citing. X Default: nil. X X Variable: sc-load-hook X User definable hook which runs after supercite is loaded. X Default: nil. X X Variable: sc-run-hook X User definable hook which runs after sc-cite-original X executes. Default: nil. X X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XSince every email/news reader uses a different buffer name or Xmajor-mode to reply in, supercite can't know ahead of time what the Xbuffer or major-mode name is. So supercite needs to leach onto Xwhatever buffer the reply is being made in, modifying the keymap and Xthe documentation string for that buffer. Many of the supercite 2.0 Xbeta testers used many different readers, so a mechanism was developed Xto provide a per-interface keymap, which installs itself into the Xbuffer's current-local-map based on the major-mode of the buffer. XThere are two variables which control the keymap that gets installed: X X Variable: sc-default-keymap X Default keymap to use if major-mode keybinding cannot X be found in sc-local-keymaps. X Keybindings: X (C-c C-r) sc-insert-reference X (C-c C-t) sc-cite X (C-c C-a) sc-recite X (C-c C-u) sc-uncite X (C-c C-i) sc-insert-citation X (C-c C-o) sc-open-line X (C-c C-q) sc-fill-paragraph-manually (also C-c q) X (C-c C-m) sc-modify-information X (C-c C-g) sc-glom-headers X (C-c C-v) sc-version X (C-c ?) sc-describe X X Variable: sc-local-keymaps X Variable which contains a list of interfaces and their X keybindings. X XSc-local-keymaps is an association list of the form: X X ((MAJOR-MODE [FUNCTION | MAJOR-MODE])*) X XWhen it is time to modify the keymap of the current buffer, supercite Xlooks up the `major-mode' of that buffer in this association list. If Xit matches the major mode with a MAJOR-MODE key, the value is Xreturned, otherwise, the default keymap is installed (see above). X XIf the MAJOR-MODE is found and the value is returned, this value is Xchecked to see if it is a list. If so, it is assumed that this value Xis a lambda expression which will set the current local keymap as Xdesired. If the value is not a list, it is assumed to be a previously Xdefined MAJOR-MODE. This new major mode is looked up and the lambda Xexpression is evaluated. Only one level of indirection is possible, Xbut this does allow you to save space when defining key bindings. X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XThere are a number of interactive commands that are provided as part Xof the supercite package. You can find out more details about each Xcommand by entering \\[describe-function] . X X Command: sc-insert-reference X Insert a reference header into the body of the text. X Key binding: \\[sc-insert-reference]. X X Command: sc-cite X Cite the region of text between point and mark. X Key binding: \\[sc-cite]. X X Command: sc-uncite X Uncite the region of text between point and mark. X Key binding: \\[sc-uncite]. X X Command: sc-recite X Recite the region of text between point and mark. X Key binding: \\[sc-recite]. X X Command: sc-insert-citation X Insert the citation string at the beginning of the X current line. X Key binding: \\[sc-insert-citation]. X X Command: sc-open-line X Insert a newline and leave point before it. Also, insert the X citation string at the beginning of the new line. X Key binding: \\[sc-open-line]. X X Command: sc-fill-paragraph-manually X Fill paragraph containing or following point by running X the hook, sc-fill-paragraph-hook. X Key binding: \\[sc-fill-paragraph-manually]. X X Command: sc-modify-information X Interactively add, delete or modify a key value in the X attribution list sc-gal-information. X Key binding: \\[sc-modify-information]. X X Command: sc-glom-headers X Glom information from mail headers in region between point X and mark. X Key binding: \\[sc-glom-headers]. X X Command: sc-version X Show the supercite version number. X Key binding: \\[sc-version]. X X Command: sc-describe X Describe the supercite package. X Key binding: \\[sc-describe]. X X X-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* X XEnjoy, and please send the author your compliments, questions, Xsuggestions and bug reports. Don't forget, if you're interested in Xdiscussing supercite, join the mailing list by sending mail to the Xrequest line mentioned above." X (interactive) X (describe-function 'sc-describe)) X X X;; ====================================================================== X;; load hook X(run-hooks 'sc-load-hook) END_OF_FILE if test 68078 -ne `wc -c <'supercite.el'`; then echo shar: \"'supercite.el'\" unpacked with wrong size! fi # end of 'supercite.el' fi echo shar: End of archive 2 \(of 2\). cp /dev/null ark2isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0