--- footnote.el 2017-12-17 18:40:22.940312994 -0500 +++ footnote.el_new 2017-12-17 19:00:27.713722813 -0500 @@ -131,6 +131,14 @@ has no effect on buffers already display :type 'regexp :group 'footnote) +(defcustom Footnote-align-to-fn-text t +"Nil if footnote text is to be aligned flush left with left side +of the footnote number. Non-nil if footnote text is to be aligned +left with the first character of footnote text." + :type 'boolean + :group 'footnote) +(make-variable-buffer-local 'Footnote-align-to-fn-text) + ;;; Private variables (defvar footnote-style-number nil @@ -148,6 +156,12 @@ has no effect on buffers already display (defvar footnote-mouse-highlight 'highlight "Text property name to enable mouse over highlight.") +(defvar Footnote--body-auto-fill-prefix nil +"When Footnmote mode modifies variable `fill-prefix', store the +prior value here, so that it can be restored when leaving the +footnote area.") +(make-variable-buffer-local 'Footnote--body-auto-fill-prefix) + ;;; Default styles ;;; NUMERIC (defconst footnote-numeric-regexp "[0-9]+" @@ -609,8 +623,72 @@ Return nil if the cursor is not over a f (or (get-text-property (point) 'footnote-number) (Footnote-text-under-cursor))) +(defun Footnote--calc-fn-alignment-column() +"Calculate the left alignment for footnote text." + (+ footnote-body-tag-spacing + (length + (concat footnote-start-tag footnote-end-tag + (Footnote-index-to-string + (caar (last footnote-text-marker-alist))))))) + +(defun Footnote--align-to-body() + (when (not Footnote-align-to-fn-text) + (setq fill-prefix Footnote--body-auto-fill-prefix) + (setq Footnote--body-auto-fill-prefix nil))) + +(defun Footnote--point-in-body-p() + "Return `t' if point is in the buffer text area, ie. before the beginning of +the footnote area." + ; NOTE: This code is shared with a patch I've proposed for emacs-bug#29756 + (let + ((p (point)) + (q (if (not footnote-text-marker-alist) (point-max) + (if (string-equal footnote-section-tag "") + (cdr (first footnote-text-marker-alist)) + (goto-char (cdr (first footnote-text-marker-alist))) + (if (re-search-backward + (concat "^" footnote-section-tag-regexp) nil t) + (match-beginning 0) + ; This `else' should never happen, and indicates an error, ie. footnotes + ; already exist and a footnote-section-tag is defined, but the section tag + ; hasn't been found. We choose to assume that the user deleted it + ; intentionally and wants us to behave in this buffer as if the section tag + ; was set "", so we do that, now. + (setq footnote-section-tag "") + ; HOWEVER: The rest of footnote mode does not currently honor or account + ; for this. + ; + ; To illustrate the difference in behavior, create a few footnotes, delete + ; the section tag, and create another footnote. Then undo, comment the + ; above line (that sets the tag to ""), re-evaluate this function, and repeat. + (cdr (first footnote-text-marker-alist)) + ))))) + (goto-char p) ; undo `re-search-backward' side-effect + (if (< p q) t nil))) + ;;; User functions +(defun Footnote-toggle-alignment() + "Change whether footnote text is aligned flush left with the +left of a footnote's number, or flush left with the first +character of footnote text on the footnote's first line." + (interactive) + (setq Footnote-align-to-fn-text (not Footnote-align-to-fn-text)) + (when footnote-text-marker-alist + (if (>= (point) (cdr (first footnote-text-marker-alist))) + (if Footnote-align-to-fn-text + (Footnote--align-to-fn) + (Footnote--align-to-body)))) + (if Footnote-align-to-fn-text + (message "Footnotes will left-align to footnote text") + (message "Footnotes will left-align to body text"))) + +(defun Footnote-fill-paragraph(&optional justify region) + (when (and (Footnote--point-in-body-p) Footnote--body-auto-fill-prefix) + (setq fill-prefix Footnote--body-auto-fill-prefix) + (setq Footnote--body-auto-fill-prefix nil)) + (fill-paragraph justify region)) + (defun Footnote-make-hole () (save-excursion (let ((i 0) @@ -661,7 +739,10 @@ by using `Footnote-back-to-message'." (Footnote-narrow-to-footnotes))) ;; Emacs/XEmacs bug? save-excursion doesn't restore point when using ;; insert-before-markers. - (goto-char opoint)))) + (goto-char opoint)) + (when Footnote-align-to-fn-text + (setq Footnote--body-auto-fill-prefix (or fill-prefix "")) + (setq fill-prefix (make-string (Footnote--calc-fn-alignment-column) 32))))) (defun Footnote-delete-footnote (&optional arg) "Delete a numbered footnote. @@ -767,7 +848,9 @@ being set it is automatically widened." (when note (when footnote-narrow-to-footnotes-when-editing (widen)) - (goto-char (cadr (assq note footnote-pointer-marker-alist)))))) + (goto-char (cadr (assq note footnote-pointer-marker-alist))) + (setq fill-prefix Footnote--body-auto-fill-prefix) + (setq Footnote--body-auto-fill-prefix nil)))) (defvar footnote-mode-map (let ((map (make-sparse-keymap))) @@ -778,6 +861,8 @@ being set it is automatically widened." (define-key map "g" 'Footnote-goto-footnote) (define-key map "r" 'Footnote-renumber-footnotes) (define-key map "s" 'Footnote-set-style) + (define-key map (kbd "M-q") 'Footnote-toggle-alignment) + (define-key map [remap fill-paragraph] 'Footnote-fill-paragraph) map)) (defvar footnote-minor-mode-map