[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
Re: Inserting beamer frames, Mandar Mitra, 2022/01/11