From 317990dd8a33e06f331f21a49e4c25875bfcc711 Mon Sep 17 00:00:00 2001 From: Carsten Dominik Date: Fri, 2 Jan 2009 15:53:02 +0100 Subject: [PATCH] Footnotes: Automatic label creation. This patch implements fully automatic creation of unique labels for footnotes, which is also turned on as the default setting. The automatic labels look like [fn:1], [fn:2], etc, using the first available unused number. The commit introduces a new variable, `org-footnote-auto-label' with a number of different options ranging from no auto creation (prompting the user for a label) to fully automatic creation. Also, the commit introduces new #+STARTUP options that can be used to select these settings on a per-file basis. --- ORGWEBPAGE/Changes.org | 35 +++++++++++++++++++++------------- doc/org.texi | 37 ++++++++++++++++++++++++++++++------ lisp/org-footnote.el | 43 +++++++++++++++++++++++++++++++++++++++--- lisp/org.el | 4 ++++ 4 files changed, 97 insertions(+), 22 deletions(-) diff --git a/ORGWEBPAGE/Changes.org b/ORGWEBPAGE/Changes.org index e941f70e9..fde05e821 100644 --- a/ORGWEBPAGE/Changes.org +++ b/ORGWEBPAGE/Changes.org @@ -31,14 +31,17 @@ For example: [1] The link is: http://orgmode.org #+end_src - Org-mode extends the number-based syntax to _named_ footnotes and -optional inline definition. Using numbers as markers is supported for -backward compatibility. Here are the valid references: +Org-mode extends the number-based syntax to /named/ footnotes and +optional inline definition. Using numbers as markers is +supported for backward compatibility, but not encouraged because +of possible conflicts with LaTeX syntax. Here are the valid +references: -- [1] :: A numeric footnote marker. +- [1] :: A plain numeric footnote marker. - [fn:name] :: A named footnote reference, where `name' is a - unique label word. + unique label word or, for simplicity of automatic creation, + a number. - [fn:: This is the inline definition of this footnote] :: A LaTeX-like anonymous footnote where the definition is given @@ -50,17 +53,23 @@ backward compatibility. Here are the valid references: note, you can then use use `[fn:name]' to create additional references. +Footnote labels can be created automatically, or you create names +yourself. This is handled by the variable +=org-footnote-auto-label= and its corresponding =#+STARTUP= +keywords, see the docstring of that variable for details. + The following command handles footnotes: - C-c C-x f :: - The footnote action command. When the cursor is on a footnote - reference, jump to the definition. When it is at a definition, - jump to the (first) reference. Otherwise, create a new footnote. - Depending on the variable `org-footnote-define-inline' (with - associated #+STARTUP options fninline and nofninline), the - definitions will be placed locally, or into the nearest outline - section with the heading `Footnotes'. If no such section is found - after the reference point, one will be created at the end of the + The footnote action command. When the cursor is on a + footnote reference, jump to the definition. When it is at a + definition, jump to the (first) reference. Otherwise, + create a new footnote. Depending on the variable + `org-footnote-define-inline' (with associated =#+STARTUP= + options =fninline= and =nofninline=), the definitions will + be placed locally, or into the nearest outline section with + the heading `Footnotes'. If no such section is found after + the reference point, one will be created at the end of the file. When this command is called with a prefix argument, a menu of additional options is offered: diff --git a/doc/org.texi b/doc/org.texi index ab4c01667..d88457659 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -1379,20 +1379,23 @@ brackets in column 0, no indentation allowed. The footnote reference is simply the marker in square brackets, inside text. For example: @example -The Org homepage[1] now looks a lot better than it used to. +The Org homepage[fn:1] now looks a lot better than it used to. ... -[1] The link is: http://orgmode.org +[fn:1] The link is: http://orgmode.org @end example Org-mode extends the number-based syntax to @emph{named} footnotes and -optional inline definition. Using numbers as markers is supported for -backward compatibility. Here are the valid references: +optional inline definition. Using plain numbers as markers (as +@file{footnote.el} does) is supported for backward compatibility, but not +encouraged because of possible conflicts with LaTeX snippets @pxref{Embedded +LaTeX}. Here are the valid references: @table @code @item [1] -A numeric footnote marker. +A plain numeric footnote marker. @item [fn:name] -A named footnote reference, where @code{name} is a unique label word. +A named footnote reference, where @code{name} is a unique label word, or, for +simplicity of automatic creation, a number. @item [fn:: This is the inline definition of this footnote] A LaTeX-like anonymous footnote where the definition is given directly at the reference point. @@ -1402,6 +1405,11 @@ Since Org allows multiple references to the same note, you can then use use @code{[fn:name]} to create additional references. @end table +Footnote labels can be created automatically, or you create names yourself. +This is handled by the variable @code{org-footnote-auto-label} and its +corresponding @code{#+STARTUP} keywords, see the docstring of that variable +for details. + @noindent The following command handles footnotes: @table @kbd @@ -8819,6 +8827,23 @@ The following options influence the table spreadsheet (variable constcgs @r{@file{constants.el} should use the c-g-s unit system} constSI @r{@file{constants.el} should use the SI unit system} @end example +To influence footnote settings, use the following keywords. The +corresponding variables are @code{org-footnote-define-inline} and +@code{org-footnote-auto-label}. +@cindex @code{fninline}, STARTUP keyword +@cindex @code{fnnoinline}, STARTUP keyword +@cindex @code{fnprompt}, STARTUP keyword +@cindex @code{fnauto}, STARTUP keyword +@cindex @code{fnconfirm}, STARTUP keyword +@cindex @code{fnplain}, STARTUP keyword +@example +fninline @r{define footnotes inline} +fnnoinline @r{define footnotes in separate section} +fnprompt @r{prompt for footnote labels} +fnauto @r{create [fn:1]-like labels automatically (default)} +fnconfirm @r{offer automatic label for editing or confirmation} +fnplain @r{create [1]-like labels automatically} +@end example @item #+TAGS: TAG1(c1) TAG2(c2) These lines (several such lines are allowed) specify the valid tags in this file, and (potentially) the corresponding @emph{fast tag selection} diff --git a/lisp/org-footnote.el b/lisp/org-footnote.el index 757187601..d2e1c358f 100644 --- a/lisp/org-footnote.el +++ b/lisp/org-footnote.el @@ -92,6 +92,23 @@ will be used to define the footnote at the reference position." :group 'org-footnote :type 'boolean) +(defcustom org-footnote-auto-label t + "Non-nil means, define automatically new labels for footnotes. +Possible values are: + +nil prompt the user for each label +t create unique labels of the form [fn:1], [fn:2], ... +confirm like t, but let the user edit the created value. In particular, + the label can be removed from the minibuffer, to create + an anonymous footnote. +plain Automatically create plain number labels like [1]" + :group 'org-footnote + :type '(choice + (const :tag "Frompt for label" nil) + (const :tag "Create automatic [fn:N]" t) + (const :tag "Offer automatic [fn:N] for editing" confirm) + (const :tag "Create automatic [N]" plain))) + (defun org-footnote-at-reference-p () "Is the cursor at a footnote reference? If yes, return the beginning position, the label, and the definition, if local." @@ -175,6 +192,20 @@ with start and label of the footnote if there is a definition at point." (and l (not (equal l "fn:")) (add-to-list 'rtn l))))) rtn)) +(defun org-footnote-unique-label (&optional current) + "Return a new unique footnote label. +The returns the firsts fn:N labels that is currently not used." + (unless current (setq current (org-footnote-all-labels))) + (let ((fmt (if (eq org-footnote-auto-label 'plain) "%d" "fn:%d")) + (cnt 1)) + (while (member (format fmt cnt) current) + (incf cnt)) + (format fmt cnt))) + +(defvar org-footnote-label-history nil + "History of footnote labels entered in current buffer.") +(make-variable-buffer-local 'org-footnote-label-history) + (defun org-footnote-new () "Insert a new footnote. This command prompts for a label. If this is a label referencing an @@ -182,9 +213,15 @@ existing label, only insert the label. If the footnote label is empty or new, let the user edit the definition of the footnote." (interactive) (let* ((labels (org-footnote-all-labels)) - (label (completing-read - "Label (leave empty for anonymous): " - (mapcar 'list labels)))) + (propose (org-footnote-unique-label labels)) + (label + (if (member org-footnote-auto-label '(t plain)) + propose + (completing-read + "Label (leave empty for anonymous): " + (mapcar 'list labels) nil nil + (if (eq org-footnote-auto-label 'confirm) propose nil) + 'org-footnote-label-history)))) (setq label (org-footnote-normalize-label label)) (cond ((equal label "") diff --git a/lisp/org.el b/lisp/org.el index c7d49bc7f..9200144ec 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -2995,6 +2995,10 @@ After a match, the following groups carry important information: ("nologrepeat" org-log-repeat nil) ("fninline" org-footnote-define-inline t) ("nofninline" org-footnote-define-inline nil) + ("fnauto" org-footnote-auto-label t) + ("fnprompt" org-footnote-auto-label nil) + ("fnconfirm" org-footnote-auto-label confirm) + ("fnplain" org-footnote-auto-label plain) ("constcgs" constants-unit-system cgs) ("constSI" constants-unit-system SI)) "Variable associated with STARTUP options for org-mode.