auctex-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Update fancyvrb.el for reflabel key


From: Arash Esbati
Subject: Update fancyvrb.el for reflabel key
Date: Wed, 09 Sep 2020 23:20:13 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50

Hi all,

starting with v3.6 dated 2020/05/03 fancyvrb.sty provides a key
"reflabel" or page references to verbatim environments.  I've updated
fancyvrb.el to support this key both in AUCTeX and RefTeX.  Before
pushing this change, are there any fancyvrb.sty users around who can
test this?  The patch is attached below; the style file is attached to
the message.

Any comments welcome.  Best, Arash

--8<---------------cut here---------------start------------->8---
diff --git a/style/fancyvrb.el b/style/fancyvrb.el
index ee046b71..9cb24a76 100644
--- a/style/fancyvrb.el
+++ b/style/fancyvrb.el
@@ -1,4 +1,4 @@
-;;; fancyvrb.el --- AUCTeX style for `fancyvrb.sty' version 3.0.
+;;; fancyvrb.el --- AUCTeX style for `fancyvrb.sty' version 3.6.

 ;; Copyright (C) 2013, 2014, 2016-2018, 2020 Free Software Foundation, Inc.

@@ -25,7 +25,7 @@

 ;;; Commentary:

-;; This file adds support for `fancyvrb.sty' version 3.0.
+;; This file adds support for `fancyvrb.sty' version 3.6.

 ;; This style has some capabilities to parse user defined macros,
 ;; environments and saved blocks with `SaveVerbatim' environments and
@@ -41,6 +41,18 @@
 ;; The entries in `LaTeX-fancyvrb-key-val-options' cover also some
 ;; keys which are not mentioned in the manual of the package.

+;; Starting with version 3.6, fancyvrb.sty provides a `reflabel' key
+;; in the optional arguments which acts like a `\label' macro.  This
+;; key makes mostly sense for `\pageref'; referencing number of
+;; missing \caption's with `\ref' in a fancyvrb environment isn't
+;; useful.  This style provides support for AUCTeX and RefTeX in order
+;; to add and reference these labels.  When inserting an environment
+;; with `C-c C-e', choose `reflabel' key during the completion.  If
+;; you're using RefTeX and want to pass the label insertion job to it,
+;; simply leave the key value-less and proceed.  Otherwise enter the
+;; label value by yourself.  AUCTeX and RefTeX will parse the value
+;; and offer it for completion once a referencing macros is used.
+
 ;;; Code:

 ;; Needed for auto-parsing:
@@ -59,8 +71,7 @@
   `(("commentchar" ("none"))
     ("gobble")
     ("formatcom")
-    ;; Undocumented key
-    ("formatcom*")
+    ("formatcom*")    ; Undocumented key
     ("fontfamily" ("tt" "courier" "helvetica"))
     ("fontsize"   ("auto" "\\tiny" "\\scriptsize"
                   "\\footnotesize" "\\small" "\\normalsize"
@@ -93,11 +104,10 @@
     ("hfuzz")
     ("samepage" ("true" "false"))
     ("codes")
-    ;; Undocumented key
-    ("codes*")
+    ("codes*")        ; Undocumented key
     ("defineactive")
-    ;; Undocumented key
-    ("defineactive*")
+    ("defineactive*") ; Undocumented key
+    ("reflabel")
     ;; Undocumented key and introduced in version 2.81 2011/04/06
     ("vspace" ,(mapcar (lambda (x)
                         (concat TeX-esc (car x)))
@@ -355,16 +365,61 @@ update only various AUCTeX variables for verbatim 
environments."
             ;; (cond ...):
             (LaTeX-add-environments
              `(,env LaTeX-env-args
-                    [ TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local ]))
+                    [ TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local ]
+                    LaTeX-fancyvrb-env-reflabel-key-val))
             (LaTeX-add-environments
              `(,(concat env "*") LaTeX-env-args
-               [ TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local ]))
+               [ TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local ]
+               LaTeX-fancyvrb-env-reflabel-key-val))
             (add-to-list 'LaTeX-verbatim-environments-local (concat env "*"))
             (add-to-list 'LaTeX-indent-environment-list
-                         `(,(concat env "*") current-indentation) t)))
+                         `(,(concat env "*") current-indentation) t)
+            ;; Tell AUCTeX about label values to reflabel key:
+            (add-to-list 'LaTeX-label-alist
+                         (cons env 'LaTeX-listing-label) t)
+            (add-to-list 'LaTeX-label-alist
+                         (cons (concat env "*") 'LaTeX-listing-label) t)
+            (TeX-auto-add-regexp
+             `(,(concat  (regexp-quote TeX-esc)
+                         "begin[[:space:]]*"
+                         (regexp-quote TeX-grop)
+                         env
+                         "\\*?"
+                         (regexp-quote TeX-grcl)
+                         "[[:space:]]*"
+                         (LaTeX-extract-key-value-label "reflabel"))
+               1 LaTeX-auto-label))
+            ;; Tell RefTeX:
+            (when (and (fboundp 'reftex-add-label-environments)
+                       (boundp 'reftex-label-regexps))
+              (reftex-add-label-environments
+               `((,env
+                  ?l "lst:" "~\\pageref{%s}"
+                  LaTeX-fancyvrb-reftex-label-context-function
+                  (regexp "[Ll]isting" "[Vv]erbatim"
+                          "[Cc]ode"    "Quell\\(code\\|text\\)"))
+
+                 (,(concat env "*")
+                  ?l "lst:" "~\\pageref{%s}"
+                  LaTeX-fancyvrb-reftex-label-context-function
+                  (regexp "[Ll]isting" "[Vv]erbatim"
+                          "[Cc]ode"    "Quell\\(code\\|text\\)"))))
+              (add-to-list 'reftex-label-regexps
+                           (concat
+                            (regexp-quote TeX-esc)
+                            "begin[[:space:]]*"
+                            (regexp-quote TeX-grop)
+                            (concat env "\\*?")
+                            (regexp-quote TeX-grcl)
+                            "[[:space:]]*"
+                            (LaTeX-extract-key-value-label "reflabel" 1))
+                           t))))
       ;; These apply for all environments defined:
       (add-to-list 'LaTeX-verbatim-environments-local env)
       (add-to-list 'LaTeX-indent-environment-list `(,env current-indentation) 
t)))
+  ;; Update RefTeX:
+  (when (fboundp 'reftex-compile-variables)
+    (reftex-compile-variables))
   ;; Update font-lock:
   (when (and (fboundp 'font-latex-set-syntactic-keywords)
             (eq TeX-install-font-lock 'font-latex-setup))
@@ -379,6 +434,80 @@ If OPTIONAL is non-nil, insert the file name in brackets."
     (TeX-master-directory))
    optional))

+(defun LaTeX-fancyvrb-env-reflabel-key-val (_optional)
+  "Add a label value to reflabel key.
+This function checks if the reflabel key is given in the optional
+argument of a fancyvrb environment and then adds a label as value
+to that key.  The label value is inserted only if the key is
+value-less; user entered label values are recognized and
+respected.  OPTIONAL is ignored."
+  (let ((p (point-marker))
+       (s (make-marker)))
+    (set-marker s (save-excursion
+                   (LaTeX-find-matching-begin)
+                   (re-search-forward (regexp-quote LaTeX-optop)
+                                      p t)))
+    ;; Search for the reflabel and a potential value:
+    (re-search-backward
+     (concat
+      "\\(reflabel\\)"
+      ;; Check if the key already has a label value:
+      "\\("
+      "[[:space:]]*=[[:space:]]*"
+      (regexp-quote TeX-grop)
+      "?"
+      "[[:alnum:]:._-]"
+      "\\)?")
+     s t)
+    ;; Insert a label value only if the key is value-less:
+    (when (and (not (match-string 2))
+              (match-string 1))
+      (goto-char (match-end 1))
+      (insert "="
+             TeX-grop
+             (format "%s" (LaTeX-label (LaTeX-current-environment)
+                                       'environment
+                                       t))
+             TeX-grcl))
+    ;; At any rate, go to where we started and clean up:
+    (goto-char p)
+    (set-marker p nil)
+    (set-marker s nil)))
+
+(defun LaTeX-fancyvrb-reftex-label-context-function (env)
+  "Extract and return a context string for RefTeX.
+The context string is the first line of the verbatim environment.
+If no reflabel key is found, an error is issued.
+ENV is the name of current environment as a string."
+  (let* ((envstart (save-excursion
+                    (re-search-backward (concat "\\\\begin{" env "}")
+                                        nil t)))
+        (label-key (save-excursion
+                     (re-search-backward "\\<reflabel[ \t\n\r%]*=[ \t\n\r%]*"
+                                         envstart t))))
+    (if label-key
+       (save-excursion
+         (goto-char envstart)
+         (re-search-forward (regexp-quote TeX-grcl) label-key t)
+         (forward-list)
+         (forward-line)
+         ;; Return the first line of verbatim env:
+         (buffer-substring-no-properties (point)
+                                         (line-end-position)))
+      (error "No label found"))))
+
+(defvar LaTeX-fancyvrb-key-val-label-regexp
+  `(,(concat
+      (regexp-quote TeX-esc)
+      "begin[[:space:]]*"
+      (regexp-quote TeX-grop)
+      "\\(?:BVerbatim\\*?\\|LVerbatim\\*?\\|Verbatim\\*?\\)"
+      (regexp-quote TeX-grcl)
+      "[[:space:]]*"
+      (LaTeX-extract-key-value-label "reflabel"))
+    1 LaTeX-auto-label)
+  "Matches the label inside an optional argument of fancyvrb environments.")
+
 (TeX-add-style-hook
  "fancyvrb"
  (lambda ()
@@ -386,6 +515,7 @@ If OPTIONAL is non-nil, insert the file name in brackets."
    (TeX-auto-add-regexp LaTeX-fancyvrb-environment-regexp)
    (TeX-auto-add-regexp LaTeX-fancyvrb-saveverb-regexp)
    (TeX-auto-add-regexp LaTeX-fancyvrb-saveverbatim-regexp)
+   (TeX-auto-add-regexp LaTeX-fancyvrb-key-val-label-regexp)
    (TeX-run-style-hooks
     "keyval")

@@ -469,17 +599,23 @@ If OPTIONAL is non-nil, insert the file name in brackets."

    (LaTeX-add-environments
     '("Verbatim" LaTeX-env-args
-      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local])
+      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local]
+      LaTeX-fancyvrb-env-reflabel-key-val)
     '("Verbatim*" LaTeX-env-args
-      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local])
+      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local]
+      LaTeX-fancyvrb-env-reflabel-key-val)
     '("BVerbatim" LaTeX-env-args
-      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local])
+      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local]
+      LaTeX-fancyvrb-env-reflabel-key-val)
     '("BVerbatim*" LaTeX-env-args
-      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local])
+      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local]
+      LaTeX-fancyvrb-env-reflabel-key-val)
     '("LVerbatim" LaTeX-env-args
-      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local])
+      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local]
+      LaTeX-fancyvrb-env-reflabel-key-val)
     '("LVerbatim*" LaTeX-env-args
-      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local])
+      [TeX-arg-key-val LaTeX-fancyvrb-key-val-options-local]
+      LaTeX-fancyvrb-env-reflabel-key-val)
     '("SaveVerbatim"
       (lambda (env)
        (let ((options (TeX-read-key-val t 
LaTeX-fancyvrb-key-val-options-local))
@@ -501,6 +637,41 @@ If OPTIONAL is non-nil, insert the file name in brackets."
                     (concat LaTeX-optop options LaTeX-optcl))
                   (concat TeX-grop file TeX-grcl)))))))

+   (let ((envs '("BVerbatim" "BVerbatim*"
+                "LVerbatim" "LVerbatim*"
+                "Verbatim"  "Verbatim*")))
+     ;; Add pre-defined environments to `LaTeX-label-alist':
+     (dolist (env envs)
+       (add-to-list 'LaTeX-label-alist (cons env 'LaTeX-listing-label) t))
+
+     ;; Tell RefTeX
+     (when (and (fboundp 'reftex-add-label-environments)
+               (fboundp 'reftex-compile-variables)
+               (boundp 'reftex-label-regexps))
+       (dolist (env envs)
+        (reftex-add-label-environments
+         `((,env ?l "lst:" "~\\pageref{%s}"
+                 LaTeX-fancyvrb-reftex-label-context-function
+                 (regexp "[Ll]isting" "[Vv]erbatim"
+                         "[Cc]ode"    "Quell\\(code\\|text\\)")))))
+
+       (unless (string-match "\\<reflabel"
+                            (mapconcat #'identity
+                                       reftex-label-regexps
+                                       "|"))
+        (make-local-variable 'reftex-label-regexps)
+        (add-to-list 'reftex-label-regexps
+                     (concat
+                      (regexp-quote TeX-esc)
+                      "begin[[:space:]]*"
+                      (regexp-quote TeX-grop)
+                      "[BL]?Verbatim\\*?"
+                      (regexp-quote TeX-grcl)
+                      "[[:space:]]*"
+                      (LaTeX-extract-key-value-label "reflabel" 1))
+                     t)
+        (reftex-compile-variables))))
+
    (LaTeX-add-counters
     "FancyVerbLine")

@@ -527,6 +698,7 @@ If OPTIONAL is non-nil, insert the file name in brackets."

    ;; Fontification
    (when (and (fboundp 'font-latex-add-keywords)
+             (fboundp 'font-latex-set-syntactic-keywords)
              (eq TeX-install-font-lock 'font-latex-setup))
      (font-latex-add-keywords '(("CustomVerbatimCommand"       "|{\\{{")
                                ("RecustomVerbatimCommand"     "|{\\{{")
@@ -546,7 +718,8 @@ If OPTIONAL is non-nil, insert the file name in brackets."
                                ("UseVerbatim"  "{")
                                ("LUseVerbatim" "{")
                                ("BUseVerbatim" "{"))
-                             'textual)))
+                             'textual)
+     (font-latex-set-syntactic-keywords)))
  LaTeX-dialect)

 (defvar LaTeX-fancyvrb-package-options nil
--8<---------------cut here---------------end--------------->8---

Attachment: fancyvrb.el.gz
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]