diff options
| author | Boruch Baum | 2017-12-22 21:44:52 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2017-12-22 21:44:52 -0500 |
| commit | 4ee066381cfe941f58040c117fec83a9712cc80a (patch) | |
| tree | 0cce12b04054db85472b9a37d6b6aa5449bd6f9c | |
| parent | 3404a87f29b28b449a2e6188f075df2f761caac5 (diff) | |
| download | emacs-4ee066381cfe941f58040c117fec83a9712cc80a.tar.gz emacs-4ee066381cfe941f58040c117fec83a9712cc80a.zip | |
* lisp/mail/footnote.el: Misc changes in preparation for more
(footnote-section-tag-regexp): Don't require the trailing space.
(Footnote--point-in-body-p, Footnote--get-area-point-min)
(Footnote--get-area-point-max): New functions.
(Footnote-narrow-to-footnotes, Footnote-text-under-cursor): Use them.
| -rw-r--r-- | lisp/mail/footnote.el | 142 |
1 files changed, 106 insertions, 36 deletions
diff --git a/lisp/mail/footnote.el b/lisp/mail/footnote.el index 0c39f62f3ee..272672904bf 100644 --- a/lisp/mail/footnote.el +++ b/lisp/mail/footnote.el | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | ;; Copyright (C) 1997, 2000-2017 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1997, 2000-2017 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Steven L Baur <steve@xemacs.org> | 5 | ;; Author: Steven L Baur <steve@xemacs.org> |
| 6 | ;; Boruch Baum <boruch_baum@gmx.com> | ||
| 6 | ;; Keywords: mail, news | 7 | ;; Keywords: mail, news |
| 7 | ;; Version: 0.19 | 8 | ;; Version: 0.19 |
| 8 | 9 | ||
| @@ -29,9 +30,36 @@ | |||
| 29 | ;; [1] Footnotes look something like this. Along with some decorative | 30 | ;; [1] Footnotes look something like this. Along with some decorative |
| 30 | ;; stuff. | 31 | ;; stuff. |
| 31 | 32 | ||
| 32 | ;; TODO: | 33 | ;;;; TODO: |
| 33 | ;; Reasonable Undo support. | 34 | ;; + Reasonable Undo support. |
| 34 | ;; more language styles. | 35 | ;; - could use an `apply' entry in the buffer-undo-list to be warned when |
| 36 | ;; a footnote we inserted is removed via undo. | ||
| 37 | ;; - should try to handle the more general problem of deleting/removing | ||
| 38 | ;; footnotes via standard editing commands rather than via footnote | ||
| 39 | ;; commands. | ||
| 40 | ;; + more language styles. | ||
| 41 | ;; + The key sequence 'C-c ! a C-y C-c ! b' should auto-fill the | ||
| 42 | ;; footnote in adaptive fill mode. This does not seem to be a bug in | ||
| 43 | ;; `adaptive-fill' because it behaves that way on all point movements | ||
| 44 | ;; + Handle footmode mode elegantly in all modes, even if that means refuses to | ||
| 45 | ;; accept the burden. For example, in a programming language mode, footnotes | ||
| 46 | ;; should be commented. | ||
| 47 | ;; + Manually autofilling the a first footnote should not cause it to | ||
| 48 | ;; wrap into the footnote section tag | ||
| 49 | ;; + Current solution adds a second newline after the section tag, so it is | ||
| 50 | ;; clearly a separate paragraph. There may be stylistic objections to this. | ||
| 51 | ;; + Footnotes with multiple paragraphs should not have their first | ||
| 52 | ;; line out-dented. | ||
| 53 | ;; + Upon leaving footnote area, perform an auto-fill on an entire | ||
| 54 | ;; footnote (including multiple paragraphs), or on entire footnote area. | ||
| 55 | ;; + fill-paragraph takes arg REGION, but seemingly only when called | ||
| 56 | ;; interactively. | ||
| 57 | ;; + At some point, it became necessary to change `footnote-section-tag-regexp' | ||
| 58 | ;; to remove its trailing space. (Adaptive fill side-effect?) | ||
| 59 | ;; + useful for lazy testing | ||
| 60 | ;; (setq footnote-narrow-to-footnotes-when-editing t) | ||
| 61 | ;; (setq footnote-section-tag "Footnotes: ") | ||
| 62 | ;; (setq footnote-section-tag-regexp "Footnotes\\(\\[.\\]\\)?:") | ||
| 35 | 63 | ||
| 36 | ;;; Code: | 64 | ;;; Code: |
| 37 | 65 | ||
| @@ -101,11 +129,15 @@ footnotes." | |||
| 101 | :type 'string | 129 | :type 'string |
| 102 | :group 'footnote) | 130 | :group 'footnote) |
| 103 | 131 | ||
| 104 | (defcustom footnote-section-tag-regexp "Footnotes\\(\\[.\\]\\)?: " | 132 | (defcustom footnote-section-tag-regexp |
| 133 | ;; Even if `footnote-section-tag' has a trailing space, let's not require it | ||
| 134 | ;; here, since it might be trimmed by various commands. | ||
| 135 | "Footnotes\\(\\[.\\]\\)?:" | ||
| 105 | "Regexp which indicates the start of a footnote section. | 136 | "Regexp which indicates the start of a footnote section. |
| 106 | This variable is disregarded when `footnote-section-tag' is the | 137 | This variable is disregarded when `footnote-section-tag' is the |
| 107 | empty string. Customizing this variable has no effect on buffers | 138 | empty string. Customizing this variable has no effect on buffers |
| 108 | already displaying footnotes." | 139 | already displaying footnotes." |
| 140 | :version "27.1" | ||
| 109 | :type 'regexp | 141 | :type 'regexp |
| 110 | :group 'footnote) | 142 | :group 'footnote) |
| 111 | 143 | ||
| @@ -532,20 +564,15 @@ styles." | |||
| 532 | footnote-end-tag) | 564 | footnote-end-tag) |
| 533 | 'footnote-number to))))) | 565 | 'footnote-number to))))) |
| 534 | 566 | ||
| 535 | ;; Not needed? | 567 | ;; Not needed? <-- 2017-12 Boruch: Not my comment! BUT, when I |
| 568 | ;; starting hacking the code, this function | ||
| 569 | ;; `Footnote-narrow-to-footnotes' was never narrowing, and the result | ||
| 570 | ;; wasn't breaking anything. | ||
| 536 | (defun Footnote-narrow-to-footnotes () | 571 | (defun Footnote-narrow-to-footnotes () |
| 537 | "Restrict text in buffer to show only text of footnotes." | 572 | "Restrict text in buffer to show only text of footnotes." |
| 538 | (interactive) ; testing | 573 | (interactive) ; testing |
| 539 | (goto-char (point-max)) | 574 | (narrow-to-region (Footnote--get-area-point-min) |
| 540 | (when (re-search-backward footnote-signature-separator nil t) | 575 | (Footnote--get-area-point-max))) |
| 541 | (let ((end (point))) | ||
| 542 | (cond | ||
| 543 | ((and (not (string-equal footnote-section-tag "")) | ||
| 544 | (re-search-backward | ||
| 545 | (concat "^" footnote-section-tag-regexp) nil t)) | ||
| 546 | (narrow-to-region (point) end)) | ||
| 547 | (footnote-text-marker-alist | ||
| 548 | (narrow-to-region (cdar footnote-text-marker-alist) end)))))) | ||
| 549 | 576 | ||
| 550 | (defun Footnote-goto-char-point-max () | 577 | (defun Footnote-goto-char-point-max () |
| 551 | "Move to end of buffer or prior to start of .signature." | 578 | "Move to end of buffer or prior to start of .signature." |
| @@ -625,28 +652,22 @@ styles." | |||
| 625 | (< (car e1) (car e2))))) | 652 | (< (car e1) (car e2))))) |
| 626 | 653 | ||
| 627 | (defun Footnote-text-under-cursor () | 654 | (defun Footnote-text-under-cursor () |
| 628 | "Return the number of footnote if in footnote text. | 655 | "Return the number of the current footnote if in footnote text. |
| 629 | Return nil if the cursor is not positioned over the text of | 656 | Return nil if the cursor is not positioned over the text of |
| 630 | a footnote." | 657 | a footnote." |
| 631 | (when (and (let ((old-point (point))) | 658 | (when (and footnote-text-marker-alist |
| 632 | (save-excursion | 659 | (<= (Footnote--get-area-point-min) |
| 633 | (save-restriction | 660 | (point) |
| 634 | (Footnote-narrow-to-footnotes) | 661 | (Footnote--get-area-point-max))) |
| 635 | (and (>= old-point (point-min)) | 662 | (let ((i 1) alist-txt result) |
| 636 | (<= old-point (point-max)))))) | ||
| 637 | footnote-text-marker-alist | ||
| 638 | (>= (point) (cdar footnote-text-marker-alist))) | ||
| 639 | (let ((i 1) | ||
| 640 | alist-txt rc) | ||
| 641 | (while (and (setq alist-txt (nth i footnote-text-marker-alist)) | 663 | (while (and (setq alist-txt (nth i footnote-text-marker-alist)) |
| 642 | (null rc)) | 664 | (null result)) |
| 643 | (when (< (point) (cdr alist-txt)) | 665 | (when (< (point) (cdr alist-txt)) |
| 644 | (setq rc (car (nth (1- i) footnote-text-marker-alist)))) | 666 | (setq result (car (nth (1- i) footnote-text-marker-alist)))) |
| 645 | (setq i (1+ i))) | 667 | (setq i (1+ i))) |
| 646 | (when (and (null rc) | 668 | (when (and (null result) (null alist-txt)) |
| 647 | (null alist-txt)) | 669 | (setq result (car (nth (1- i) footnote-text-marker-alist)))) |
| 648 | (setq rc (car (nth (1- i) footnote-text-marker-alist)))) | 670 | result))) |
| 649 | rc))) | ||
| 650 | 671 | ||
| 651 | (defun Footnote-under-cursor () | 672 | (defun Footnote-under-cursor () |
| 652 | "Return the number of the footnote underneath the cursor. | 673 | "Return the number of the footnote underneath the cursor. |
| @@ -654,6 +675,53 @@ Return nil if the cursor is not over a footnote." | |||
| 654 | (or (get-text-property (point) 'footnote-number) | 675 | (or (get-text-property (point) 'footnote-number) |
| 655 | (Footnote-text-under-cursor))) | 676 | (Footnote-text-under-cursor))) |
| 656 | 677 | ||
| 678 | (defun Footnote--point-in-body-p () | ||
| 679 | "Return non-nil if point is in the buffer text area, | ||
| 680 | i.e. before the beginning of the footnote area." | ||
| 681 | (< (point) (Footnote--get-area-point-min))) | ||
| 682 | |||
| 683 | (defun Footnote--get-area-point-min (&optional before-tag) | ||
| 684 | "Return start of the first footnote. | ||
| 685 | If there is no footnote area, returns `point-max'. | ||
| 686 | With optional arg BEFORE-TAG, return position of the `footnote-section-tag' | ||
| 687 | instead, if applicable." | ||
| 688 | (cond | ||
| 689 | ;; FIXME: Shouldn't we use `Footnote--get-area-point-max' instead? | ||
| 690 | ((not footnote-text-marker-alist) (point-max)) | ||
| 691 | ((not before-tag) (cdr (first footnote-text-marker-alist))) | ||
| 692 | ((string-equal footnote-section-tag "") | ||
| 693 | (cdr (first footnote-text-marker-alist))) | ||
| 694 | (t | ||
| 695 | (save-excursion | ||
| 696 | (goto-char (cdr (first footnote-text-marker-alist))) | ||
| 697 | (if (re-search-backward (concat "^" footnote-section-tag-regexp) nil t) | ||
| 698 | (match-beginning 0) | ||
| 699 | (message "Footnote section tag not found!") | ||
| 700 | ;; This `else' should never happen, and indicates an error, | ||
| 701 | ;; ie. footnotes already exist and a footnote-section-tag is defined, | ||
| 702 | ;; but the section tag hasn't been found. We choose to assume that the | ||
| 703 | ;; user deleted it intentionally and wants us to behave in this buffer | ||
| 704 | ;; as if the section tag was set "", so we do that, now. | ||
| 705 | ;;(setq footnote-section-tag "") | ||
| 706 | ;; | ||
| 707 | ;; HOWEVER: The rest of footnote mode does not currently honor or | ||
| 708 | ;; account for this. | ||
| 709 | ;; | ||
| 710 | ;; To illustrate the difference in behavior, create a few footnotes, | ||
| 711 | ;; delete the section tag, and create another footnote. Then undo, | ||
| 712 | ;; comment the above line (that sets the tag to ""), re-evaluate this | ||
| 713 | ;; function, and repeat. | ||
| 714 | ;; | ||
| 715 | ;; TODO: integrate sanity checks at reasonable operational points. | ||
| 716 | (cdr (first footnote-text-marker-alist))))))) | ||
| 717 | |||
| 718 | (defun Footnote--get-area-point-max () | ||
| 719 | "Return the end of footnote area. | ||
| 720 | This is either `point-max' or the start of a `.signature' string, as | ||
| 721 | defined by variable `footnote-signature-separator'. If there is no | ||
| 722 | footnote area, returns `point-max'." | ||
| 723 | (save-excursion (Footnote-goto-char-point-max))) | ||
| 724 | |||
| 657 | ;;; User functions | 725 | ;;; User functions |
| 658 | 726 | ||
| 659 | (defun Footnote-make-hole () | 727 | (defun Footnote-make-hole () |
| @@ -739,7 +807,7 @@ delete the footnote with that number." | |||
| 739 | (point) | 807 | (point) |
| 740 | (if footnote-spaced-footnotes | 808 | (if footnote-spaced-footnotes |
| 741 | (search-forward "\n\n" nil t) | 809 | (search-forward "\n\n" nil t) |
| 742 | (save-restriction | 810 | (save-restriction ; <= 2017-12 Boruch: WHY?? I see no narrowing / widening here. |
| 743 | (end-of-line) | 811 | (end-of-line) |
| 744 | (next-single-char-property-change | 812 | (next-single-char-property-change |
| 745 | (point) 'footnote-number nil (Footnote-goto-char-point-max)))))) | 813 | (point) 'footnote-number nil (Footnote-goto-char-point-max)))))) |
| @@ -855,6 +923,8 @@ play around with the following keys: | |||
| 855 | (make-local-variable 'footnote-start-tag) | 923 | (make-local-variable 'footnote-start-tag) |
| 856 | (make-local-variable 'footnote-end-tag) | 924 | (make-local-variable 'footnote-end-tag) |
| 857 | 925 | ||
| 926 | ;; filladapt is an XEmacs package which AFAIK has never been ported | ||
| 927 | ;; to Emacs. | ||
| 858 | (when (boundp 'filladapt-token-table) | 928 | (when (boundp 'filladapt-token-table) |
| 859 | ;; add tokens to filladapt to match footnotes | 929 | ;; add tokens to filladapt to match footnotes |
| 860 | ;; 1] xxxxxxxxxxx x x x or [1] x x x x x x x | 930 | ;; 1] xxxxxxxxxxx x x x or [1] x x x x x x x |