Add arch taglines
[bpt/emacs.git] / lisp / mail / footnote.el
CommitLineData
e8af40ee 1;;; footnote.el --- footnote support for message mode -*- coding: iso-latin-1;-*-
55492d86 2
5404d9b0 3;; Copyright (C) 1997, 2000 by Free Software Foundation, Inc.
55492d86
DL
4
5;; Author: Steven L Baur <steve@xemacs.org>
6;; Keywords: mail, news
7;; Version: 0.19
8
409f8a3f 9;; This file is part of GNU Emacs.
55492d86 10
409f8a3f 11;; GNU Emacs is free software; you can redistribute it and/or modify it
55492d86
DL
12;; under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
409f8a3f 16;; GNU Emacs is distributed in the hope that it will be useful, but
55492d86
DL
17;; WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19;; General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
409f8a3f 22;; along with GNU Emacs; see the file COPYING. If not, write to the Free
55492d86
DL
23;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24;; 02111-1307, USA.
25
55492d86
DL
26;;; Commentary:
27
28;; This file provides footnote[1] support for message-mode in emacsen.
29;; footnote-mode is implemented as a minor mode.
30
31;; [1] Footnotes look something like this. Along with some decorative
32;; stuff.
33
34;; TODO:
35;; Reasonable Undo support.
36;; more language styles.
37
55492d86
DL
38;;; Code:
39
409f8a3f
DL
40(eval-when-compile
41 (require 'cl)
42 (defvar filladapt-token-table))
43
55492d86
DL
44(defgroup footnote nil
45 "Support for footnotes in mail and news messages."
5404d9b0 46 :version "21.1"
55492d86
DL
47 :group 'message)
48
55492d86
DL
49(defcustom footnote-mode-line-string " FN"
50 "*String to display in modes section of the mode-line."
51 :group 'footnote)
52
53(defcustom footnote-mode-hook nil
54 "*Hook functions run when footnote-mode is activated."
55 :type 'hook
56 :group 'footnote)
57
58(defcustom footnote-narrow-to-footnotes-when-editing nil
59 "*If set, narrow to footnote text body while editing a footnote."
60 :type 'boolean
61 :group 'footnote)
62
63(defcustom footnote-prompt-before-deletion t
64 "*If set, prompt before deleting a footnote.
65There is currently no way to undo deletions."
66 :type 'boolean
67 :group 'footnote)
68
69(defcustom footnote-spaced-footnotes t
70 "If set true it will put a blank line between each footnote.
71If nil, no blank line will be inserted."
72 :type 'boolean
73 :group 'footnote)
74
55492d86
DL
75(defcustom footnote-use-message-mode t
76 "*If non-nil assume Footnoting will be done in message-mode."
77 :type 'boolean
78 :group 'footnote)
79
80(defcustom footnote-body-tag-spacing 2
81 "*Number of blanks separating a footnote body tag and its text."
82 :type 'integer
83 :group 'footnote)
84
55492d86
DL
85(defvar footnote-prefix [(control ?c) ?!]
86 "*When not using message mode, the prefix to bind in `mode-specific-map'")
87
88;;; Interface variables that probably shouldn't be changed
89
90(defconst footnote-section-tag "Footnotes: "
91 "*Tag inserted at beginning of footnote section.")
92
5404d9b0
DL
93(defcustom footnote-section-tag-regexp "Footnotes\\(\\[.\\]\\)?: "
94 "*Regexp which indicates the start of a footnote section.
95See also `footnote-section-tag'."
96 :type 'regexp
97 :group 'footnote)
55492d86
DL
98
99;; The following three should be consumed by footnote styles.
5404d9b0
DL
100(defcustom footnote-start-tag "["
101 "*String used to denote start of numbered footnote."
102 :type 'string
103 :group 'footnote)
55492d86 104
5404d9b0
DL
105(defcustom footnote-end-tag "]"
106 "*String used to denote end of numbered footnote."
107 :type 'string
108 :group 'footnote)
55492d86
DL
109
110(defvar footnote-signature-separator (if (boundp 'message-signature-separator)
111 message-signature-separator
112 "^-- $")
113 "*String used to recognize .signatures.")
114
115;;; Private variables
116
117(defvar footnote-style-number nil
118 "Footnote style represented as an index into footnote-style-alist.")
119(make-variable-buffer-local 'footnote-style-number)
120
121(defvar footnote-text-marker-alist nil
122 "List of markers pointing to text of footnotes in message buffer.")
123(make-variable-buffer-local 'footnote-text-marker-alist)
124
125(defvar footnote-pointer-marker-alist nil
126 "List of markers pointing to footnote pointers in message buffer.")
127(make-variable-buffer-local 'footnote-pointer-marker-alist)
128
129(defvar footnote-mouse-highlight 'highlight
130 "Text property name to enable mouse over highlight.")
131
132(defvar footnote-mode nil
133 "Variable indicating whether footnote minor mode is active.")
134(make-variable-buffer-local 'footnote-mode)
135
136;;; Default styles
137;;; NUMERIC
138(defconst footnote-numeric-regexp "[0-9]"
139 "Regexp for digits.")
140
141(defun Footnote-numeric (n)
142 "Numeric footnote style.
143Use Arabic numerals for footnoting."
144 (int-to-string n))
145
146;;; ENGLISH UPPER
147(defconst footnote-english-upper "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
148 "Upper case English alphabet.")
149
150(defconst footnote-english-upper-regexp "[A-Z]"
151 "Regexp for upper case English alphabet.")
152
153(defun Footnote-english-upper (n)
154 "Upper case English footnoting.
155Wrapping around the alphabet implies successive repetitions of letters."
156 (let* ((ltr (mod (1- n) (length footnote-english-upper)))
157 (rep (/ (1- n) (length footnote-english-upper)))
158 (chr (char-to-string (aref footnote-english-upper ltr)))
159 rc)
160 (while (>= rep 0)
161 (setq rc (concat rc chr))
162 (setq rep (1- rep)))
163 rc))
a1506d29 164
55492d86
DL
165;;; ENGLISH LOWER
166(defconst footnote-english-lower "abcdefghijklmnopqrstuvwxyz"
167 "Lower case English alphabet.")
168
169(defconst footnote-english-lower-regexp "[a-z]"
170 "Regexp of lower case English alphabet.")
171
172(defun Footnote-english-lower (n)
173 "Lower case English footnoting.
174Wrapping around the alphabet implies successive repetitions of letters."
175 (let* ((ltr (mod (1- n) (length footnote-english-lower)))
176 (rep (/ (1- n) (length footnote-english-lower)))
177 (chr (char-to-string (aref footnote-english-lower ltr)))
178 rc)
179 (while (>= rep 0)
180 (setq rc (concat rc chr))
181 (setq rep (1- rep)))
182 rc))
183
184;;; ROMAN LOWER
185(defconst footnote-roman-lower-list
186 '((1 . "i") (5 . "v") (10 . "x")
187 (50 . "l") (100 . "c") (500 . "d") (1000 . "m"))
188 "List of roman numerals with their values.")
189
190(defconst footnote-roman-lower-regexp "[ivxlcdm]"
191 "Regexp of roman numerals.")
192
193(defun Footnote-roman-lower (n)
194 "Generic Roman number footnoting."
195 (Footnote-roman-common n footnote-roman-lower-list))
196
197;;; ROMAN UPPER
198(defconst footnote-roman-upper-list
199 '((1 . "I") (5 . "V") (10 . "X")
200 (50 . "L") (100 . "C") (500 . "D") (1000 . "M"))
201 "List of roman numerals with their values.")
202
203(defconst footnote-roman-upper-regexp "[IVXLCDM]"
204 "Regexp of roman numerals. Not complete")
205
206(defun Footnote-roman-upper (n)
207 "Generic Roman number footnoting."
208 (Footnote-roman-common n footnote-roman-upper-list))
209
210(defun Footnote-roman-common (n footnote-roman-list)
211 "Lower case Roman footnoting."
212 (let* ((our-list footnote-roman-list)
213 (rom-lngth (length our-list))
214 (rom-high 0)
215 (rom-low 0)
216 (rom-div -1)
217 (count-high 0)
218 (count-low 0))
219 ;; find surrounding numbers
220 (while (and (<= count-high (1- rom-lngth))
221 (>= n (car (nth count-high our-list))))
222 ;; (message "Checking %d" (car (nth count-high our-list)))
223 (setq count-high (1+ count-high)))
224 (setq rom-high count-high)
225 (setq rom-low (1- count-high))
226 ;; find the appropriate divisor (if it exists)
227 (while (and (= rom-div -1)
228 (< count-low rom-high))
229 (when (or (> n (- (car (nth rom-high our-list))
230 (/ (car (nth count-low our-list))
231 2)))
232 (= n (- (car (nth rom-high our-list))
233 (car (nth count-low our-list)))))
234 (setq rom-div count-low))
235 ;; (message "Checking %d and %d in div loop" rom-high count-low)
236 (setq count-low (1+ count-low)))
237 ;;(message "We now have high: %d, low: %d, div: %d, n: %d"
238 ;; rom-high rom-low (if rom-div rom-div -1) n)
239 (let ((rom-low-pair (nth rom-low our-list))
240 (rom-high-pair (nth rom-high our-list))
241 (rom-div-pair (if (not (= rom-div -1)) (nth rom-div our-list) nil)))
242 ;; (message "pairs are: rom-low: %S, rom-high: %S, rom-div: %S"
243 ;; rom-low-pair rom-high-pair rom-div-pair)
244 (cond
245 ((< n 0) (error "Footnote-roman-common called with n < 0"))
246 ((= n 0) "")
247 ((= n (car rom-low-pair)) (cdr rom-low-pair))
248 ((= n (car rom-high-pair)) (cdr rom-high-pair))
249 ((= (car rom-low-pair) (car rom-high-pair))
250 (concat (cdr rom-low-pair)
251 (Footnote-roman-common
252 (- n (car rom-low-pair))
253 footnote-roman-list)))
254 ((>= rom-div 0) (concat (cdr rom-div-pair) (cdr rom-high-pair)
255 (Footnote-roman-common
256 (- n (- (car rom-high-pair)
257 (car rom-div-pair)))
258 footnote-roman-list)))
259 (t (concat (cdr rom-low-pair)
260 (Footnote-roman-common
261 (- n (car rom-low-pair))
262 footnote-roman-list)))))))
263
5404d9b0
DL
264;; Latin-1
265
266