auctex
[Top][All Lists]
Advanced

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

Re: Inserting beamer frames


From: Arash Esbati
Subject: Re: Inserting beamer frames
Date: Wed, 12 Jan 2022 10:51:58 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50

Greg Bognar <greg.bognar@startmail.com> writes:

> Thanks for the suggestions.  I wanted to try Arash's idea first.  But I'm very
> incompetent in emacs-lisp.
>
> I can write an interactive function that seems to work:
>
> (defun my-frame-title-fix ()
>   "Fix the formatting of Beamer frame titles."
>   (interactive)
>   (save-excursion
>     (previous-line)
>     (forward-char)
>     (when (string-equal "frametitle" (thing-at-point 'word 'no-properties))
>       (join-line)
>       (delete-horizontal-space))))

I suggest to write it like this:

(defun LaTeX-beamer-fix-env ()
  (interactive)
  (when (string= "frame" (LaTeX-current-environment))
    (let ((s (make-marker))
          (e (make-marker))
          (p (point-marker)))
      (set-marker s (save-excursion
                      (LaTeX-find-matching-begin)
                      (point)))
      (set-marker e (save-excursion
                      (LaTeX-find-matching-end)
                      (point)))
      (goto-char s)
      (when (re-search-forward "\\\\frametitle" e t)
        (beginning-of-line)
        (when (looking-at-p (concat "[ \t]+" (regexp-quote 
(match-string-no-properties 0))))
          (delete-indentation)
          (delete-horizontal-space)))
      (goto-char p)
      (indent-according-to-mode)
      (set-marker s nil)
      (set-marker e nil)
      (set-marker p nil))))

This way, you can invoke the function everywhere in the frame
environment whenever you want.

Or even go further and do:

(defun LaTeX-beamer-fix-doc ()
  (interactive)
  (let ((p (point-marker)))
    (goto-char (point-min))
    (while (re-search-forward "\\\\frametitle" nil t)
      (beginning-of-line)
      (when (looking-at-p (concat "[ \t]+" (regexp-quote 
(match-string-no-properties 0))))
        (delete-indentation)
        (delete-horizontal-space)
        (forward-line)))
    (goto-char p)
    (set-marker p nil)))

And run it once in a while to fix your document in one go.

> But when I try to write a function to use in LaTeX-after-insert-env-hook, I
> stumble. [...]
> I'm probably making some elementary mistake...

No, it was me.  I had a brief look at beamer.el as I made that
suggestion.  Looking closer, beamer.el defines:

'("frame"  (lambda (env &rest ignore)
             (let ((title (TeX-read-string "(Optional) Title: " nil
                                           'LaTeX-beamer-frametitle-history)))
               (LaTeX-insert-environment env)
               (unless (zerop (length title))
                 (save-excursion
                   (LaTeX-find-matching-begin)
                   (end-of-line)
                   (LaTeX-newline)
                   ;; Indent the next macro insertion and don't
                   ;; rely on the fill-function to do it:
                   (indent-according-to-mode)
                   (insert (format "\\frametitle{%s}" title))
                   ;; This works because \frametitle is a
                   ;; paragraph command.
                   (when auto-fill-function
                     (backward-char)
                     (LaTeX-fill-paragraph)))))))

`LaTeX-after-insert-env-hook' is called at the end of
`LaTeX-insert-environment', \frametitle is inserted afterwards.  Alas,
any function added to `LaTeX-after-insert-env-hook' doesn't see that
later insertion and would fail.  Therefore the functions above.

HTH.  Best, Arash



reply via email to

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