branch: externals/auctex commit 85c46564d4b5d98d56bd128d349be25db1c9e51b Author: Arash Esbati <ar...@gnu.org> Commit: Arash Esbati <ar...@gnu.org>
Add function to put labels in opt. argument of environments * doc/changes.texi: Document new feature. * latex.el (LaTeX-listing-label): New custom prefix for labels in code typesetting environments. (LaTeX-env-label-as-keyval): New function. (LaTeX-narrow-to-environment): Fix typo in docstring. --- doc/changes.texi | 21 +++++++++++++++ latex.el | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/doc/changes.texi b/doc/changes.texi index a102bbb..3688eb0 100644 --- a/doc/changes.texi +++ b/doc/changes.texi @@ -12,6 +12,27 @@ @itemize @bullet @item +@AUCTeX{} can put and parse labels in optional argument of environments. +Inserting labels is done by new function +@code{LaTeX-env-label-as-keyval}. A new custom variable +@code{LaTeX-listing-label} is available as prefix to labels in code +typesetting environments, e.g. @samp{lstlisting} environment provided by +@samp{listings} package. @code{LaTeX-listing-label} defaults to +@code{lst:}. Parsing of labels for later referencing relies on two +requirements: +@enumerate +@item +Label should come as last key-value argument, and +@item +label must be enclosed in braces, e.g. +@example +\begin@{lstlisting@}[caption=Some Caption,label=@{lst:foo@}] +... +\end@{lstlisting@} +@end example +@end enumerate + +@item The function @code{LaTeX-label} now takes a second optional argument @code{NO-INSERT}. When non-@code{nil}, @code{LaTeX-label} reads a label and returns it as a string. This argument is also passed to any diff --git a/latex.el b/latex.el index 32ccbbc..e8c3b04 100644 --- a/latex.el +++ b/latex.el @@ -909,6 +909,14 @@ insertion or nil if no label was read in." :group 'LaTeX-environment :type 'string) +(defcustom LaTeX-listing-label "lst:" + "Default prefix to listing labels. +This prefix should apply to all environments which typeset +code listings and take a caption and label." + :group 'LaTeX-label + :group 'LaTeX-environment + :type 'string) + (defcustom LaTeX-default-format "" "Default format for array and tabular environments." :group 'LaTeX-environment @@ -1241,6 +1249,78 @@ Just like array and tabular." (make-marker)))) (TeX-parse-arguments args)))) +(defun LaTeX-env-label-as-keyval (_optional &optional keyword keyvals environment) + "Query for a label and insert it in the optional argument of an environment. +OPTIONAL is ignored. Optional KEYWORD is a string to search for +in the optional argument, label is only included if KEYWORD is +found. KEYVALS is a string with key=val's read in. If nil, this +function searchs for key=val's itself. ENVIRONMENT is a string +with the name of environment, if non-nil, don't bother to find +out." + (let ((env-start (make-marker)) + (body-start (make-marker)) + (opt-start (make-marker)) + (opt-end (make-marker)) + (currenv (or environment (LaTeX-current-environment)))) + ;; Save the starting point as we will come back here + (set-marker body-start (point)) + ;; Go to the start of the current environment and save the position + (LaTeX-find-matching-begin) + (set-marker env-start (point)) + ;; Check if an opt. argument is there; assume that it starts in + ;; the same line and save the points in markers + (when (re-search-forward + (concat "\\\\begin{" currenv "}[ \t]*\\[") body-start t) + (set-marker opt-start (1- (point))) + (goto-char opt-start) + (forward-sexp) + (set-marker opt-end (1- (point)))) + ;; If keyword argument is given and keyvals argument is not given, + ;; parse the optional argument and put it into keyvals; the regexp + ;; takes care of multi-line arguments + (when (and keyword + (marker-position opt-start) + (not keyvals)) + (goto-char (1+ opt-start)) + (re-search-forward "\\(.*\\([\n\r].*\\)*\\)" opt-end t) + (setq keyvals (match-string-no-properties 0))) + ;; If keyword is given, only insert a label when keyword is found + ;; inside the keyvals. If keyword is nil, then insert a label + ;; anyways + (if (stringp keyword) + (when (and (stringp keyvals) + (not (string= keyvals "")) + (string-match (concat keyword "[ \t]*=") keyvals)) + (goto-char opt-end) + (let ((opt-label (LaTeX-label currenv 'environment t))) + (when opt-label + (insert (if (equal (preceding-char) ?,) + "label=" + ",label=") + TeX-grop opt-label TeX-grcl)))) + (let ((opt-label (LaTeX-label currenv 'environment t))) + (when opt-label + ;; Check if an opt. argument is found and go to the end if + (if (marker-position opt-end) + (progn + (goto-char opt-end) + (insert (if (equal (preceding-char) ?,) + "label=" + ",label=") + TeX-grop opt-label TeX-grcl)) + ;; Otherwise start at the beginning of environment in + ;; order to not mess with any other mandatory arguments + ;; which can be there + (goto-char env-start) + (re-search-forward (concat "\\\\begin{" currenv "}")) + (insert LaTeX-optop "label=" TeX-grop opt-label TeX-grcl LaTeX-optcl))))) + ;; Go to where we started and clean up the markers + (goto-char body-start) + (set-marker env-start nil) + (set-marker body-start nil) + (set-marker opt-start nil) + (set-marker opt-end nil))) + ;;; Item hooks (defvar LaTeX-item-list nil @@ -5421,7 +5501,7 @@ char." (defun LaTeX-narrow-to-environment (&optional count) "Make text outside current environment invisible. With optional COUNT keep visible that number of enclosing -environmens." +environments." (interactive "p") (setq count (if count (abs count) 1)) (save-excursion