auctex-devel
[Top][All Lists]
Advanced

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

Re: Support for LaTeX hooks


From: Arash Esbati
Subject: Re: Support for LaTeX hooks
Date: Fri, 28 May 2021 11:52:10 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50

Hi Keita,

Ikumi Keita <ikumi@ikumi.que.jp> writes:

>>>>>> Arash Esbati <arash@gnu.org> writes:
>>
> I still think this query should be done later. Here is the `cond'
> clause for class hook:
>
>>        ;; class/(before|after)/<doc-class> where <doc-class> is
>>        ;; optional
>>        ((member hook '("class/before" "class/after"))
>>         (let* ((TeX-file-extensions '("cls")))
>>           (unless LaTeX-global-class-files
>>             (setq LaTeX-global-class-files
>>                   (if search
>>                       (prog2
>>                           (message "Searching for LaTeX classes...")
>>                           (mapcar #'list
>>                                   (TeX-search-files-by-type 'texinputs
>>                                                             'global
>>                                                             t t))
>>                         (message "Searching for LaTeX classes...done"))
>>                     LaTeX-style-list))))
>
> With this implementation, the result of "Find file yourself? " query
> isn't used when `LaTeX-global-class-files' is non-nil. In other words,
> it would force the user to answer meaningless inquiry.
>
> How about storing lambda form which does y-or-n query in `search'
> variable, like `func', and call it when it is actually necessary?
>
>        (search (lambda ()
>                     (if (eq TeX-arg-input-file-search 'ask)
>                    (not (y-or-n-p "Find file yourself? "))
>                  TeX-arg-input-file-search)))
> [...]
>         ;; file/(before|after)/<file-name.xxx> where <file-name> is
>         ;; optional and must be with extension
>         ((member hook '("file/before" "file/after"))
>          (if (funcall search)
>              ^^^^^^^^^^^^^^^^
> [...]
>         ;; class/(before|after)/<doc-class> where <doc-class> is
>         ;; optional
>         ((member hook '("class/before" "class/after"))
>          (let* ((TeX-file-extensions '("cls")))
>            (unless LaTeX-global-class-files
>              (setq LaTeX-global-class-files
>                    (if (funcall search)
>                        ^^^^^^^^^^^^^^^^
>                        (prog2
> [...]

Thanks for your comments and pushing me into "understand the code before
borrowing it" ;-)  I had a closer look starting here:

,----[ C-h v TeX-arg-input-file-search RET ]
| TeX-arg-input-file-search is a variable defined in ‘latex.el’.
| 
| Its value is t
| 
|   You can customize this variable.
| 
| If ‘TeX-arg-input-file’ should search for files.
| If the value is t, files in TeX’s search path are searched for
| and provided for completion.  The file name is then inserted
| without directory and extension.  If the value is nil, the file
| name can be specified manually and is inserted with a path
| relative to the directory of the current buffer’s file and with
| extension.  If the value is ‘ask’, you are asked for the method
| to use every time ‘TeX-arg-input-file’ is called.
`----

Important part is the last sentence: If ask, you're asked *every time*.
The way I see it, only the function `TeX-arg-input-file'[1] follows this
description, `TeX-arg-document'[2] and
`LaTeX-arg-usepackage-read-packages-with-options'[3] don't.  For example
in `TeX-arg-document', the user isn't queried once
`LaTeX-global-class-files' is non-nil, i.e., the user answers `n' once
and is never asked after that, unless user hits `C-u C-c C-n'.  That
doesn't fit the bill with "asked every time".  WDYT?

I've changed my solution accordingly.  Any comments welcome.

Best, Arash

Footnotes:
[1]  http://git.savannah.gnu.org/cgit/auctex.git/tree/latex.el#n2559

[2]  http://git.savannah.gnu.org/cgit/auctex.git/tree/latex.el#n2370

[3]  http://git.savannah.gnu.org/cgit/auctex.git/tree/latex.el#n2441


--8<---------------cut here---------------start------------->8---
(defvar TeX-global-input-files-with-extension nil
  "List of the non-local TeX input files with extension.
Initialized once at the first time you prompt for an input file
inside a file hook command.  
May be reset with `\\[universal-argument] \\[TeX-normal-mode]'.")

(defun TeX-read-hook (_optional)
  "Read a LaTeX hook."
  (let* ((hook (completing-read
                (TeX-argument-prompt nil nil "Hook")
                '("cmd"
                  "env"
                  ;; From ltfilehook-doc.pdf
                  "file/before"        "file/after"
                  "include/before"     "include/end"   "include/after"
                  "class/before"       "class/after"
                  "package/before"     "package/after"
                  ;; From lthooks-doc.pdf
                  "begindocument"
                  "begindocument/before"
                  "begindocument/end"
                  "enddocument"
                  "enddocument/afterlastpage"
                  "enddocument/afteraux"
                  "enddocument/info"
                  "enddocument/end"
                  "rmfamily"           "sffamily"
                  "ttfamily"           "normalfont"
                  "bfseries"           "bfseries/defaults"
                  "mdseries"           "mdseries/defaults"
                  ;; From ltshipout-doc.pdf
                  "shipout/before"     "shipout/after"
                  "shipout/foreground" "shipout/background"
                  "shipout/firstpage"  "shipout/lastpage"
                  ;; From ltpara-doc.pdf
                  "para/before"         "para/begin"
                  "para/end"            "para/after")))
         (place (lambda ()
                  (completing-read
                   (TeX-argument-prompt nil nil "Where")
                   (if (string= hook "cmd")
                       '("after" "before")
                     '("before" "begin" "end" "after")))))
         (search (lambda ()
                   (if (eq TeX-arg-input-file-search 'ask)
                       (not (y-or-n-p "Find file yourself? "))
                     TeX-arg-input-file-search)))
         name where files result)
    (cond ((string= hook "cmd")
           ;; cmd/<name>/<where>
           (setq name (completing-read
                       (TeX-argument-prompt nil nil "Command")
                       (TeX-symbol-list)))
           (setq where (funcall place)))

          ;; env/<name>/<where>
          ((string= hook "env")
           (setq name (completing-read
                       (TeX-argument-prompt nil nil "Environment")
                       (LaTeX-environment-list)))
           (setq where (funcall place)))

          ;; file/(before|after)/<file-name.xxx> where <file-name> is
          ;; optional and must be with extension
          ((member hook '("file/before" "file/after"))
           (if (funcall search)
               (progn
                 (unless TeX-global-input-files-with-extension
                   (setq TeX-global-input-files-with-extension
                         (prog2
                             (message "Searching for files...")
                             (mapcar #'list
                                     (TeX-search-files-by-type 'texinputs
                                                               'global
                                                               t nil))
                           (message "Searching for files...done"))))
                 (setq name
                       (completing-read
                        (TeX-argument-prompt t nil "File")
                        TeX-global-input-files-with-extension)))
             (setq name
                   (file-name-nondirectory
                    (read-file-name
                     (TeX-argument-prompt t nil "File")
                     nil "")))))

          ;; include/(before|after|end)/<file-name> where <file-name>
          ;; is optional
          ((member hook '("include/before" "include/end" "include/after"))
           (if (funcall search)
               (progn
                 (setq files
                       (prog2
                           (message "Searching for files...")
                           ;; \include looks for files with TeX content,
                           ;; so limit the search:
                           (let* ((TeX-file-extensions '("tex" "ltx")))
                             (TeX-search-files-by-type 'texinputs 'local t t))
                         (message "Searching for files...done")))
                 (setq name (completing-read
                             (TeX-argument-prompt t nil "File")
                             files)))
             (setq name
                   (file-name-base
                    (read-file-name
                     (TeX-argument-prompt t nil "File")
                     nil "")))))

          ;; class/(before|after)/<doc-class> where <doc-class> is
          ;; optional
          ((member hook '("class/before" "class/after"))
           (if (funcall search)
               (progn
                 (unless LaTeX-global-class-files
                   (setq LaTeX-global-class-files
                         (prog2
                             (message "Searching for LaTeX classes...")
                             (let* ((TeX-file-extensions '("cls")))
                               (mapcar #'list
                                       (TeX-search-files-by-type 'texinputs
                                                                 'global
                                                                 t t)))
                           (message "Searching for LaTeX classes...done"))))
                 (setq name (completing-read
                             (TeX-argument-prompt t nil "Document class")
                             LaTeX-global-class-files)))
             (setq name
                   (file-name-base
                    (read-file-name
                     (TeX-argument-prompt t nil "File")
                     nil "")))))

          ;; package/(before|after)/<pack-name> where
          ;; <pack-name> is optional
          ((member hook '("package/before" "package/after"))
           (if (funcall search)
               (progn
                 (unless LaTeX-global-package-files
                   (setq LaTeX-global-package-files
                         (prog2
                             (message "Searching for LaTeX packages...")
                             (let* ((TeX-file-extensions '("sty")))
                               (mapcar #'list
                                       (TeX-search-files-by-type 'texinputs
                                                                 'global
                                                                 t t)))
                           (message "Searching for LaTeX packages...done"))))
                 (setq name (completing-read
                             (TeX-argument-prompt t nil "Package")
                             LaTeX-global-package-files)))
             (setq name (file-name-base
                         (read-file-name
                          (TeX-argument-prompt t nil "File")
                          nil "")))))
          
          ;; User specific input for the hook or others, do nothing
          ;; and just insert `hook' later:
          (t nil))
    (if (member hook '("cmd" "env"))
        (setq result (concat hook "/" name "/" where))
      (push hook result)
      (when (and name (not (string= name "")))
        (push name result))
      (setq result (mapconcat #'identity
                              (reverse result)
                              "/")))
    (insert "\n" "\\AddToHook{" result "}")))
--8<---------------cut here---------------end--------------->8---



reply via email to

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