Posted on 2023-02-19 · 4 min read · emacs
I’ve just released version 0.3 of
Pressing the keybinding for
and then bind that to
latex-change-env
, featuring some
major improvements with regard to inline maths and macro handling; this
seems as good a time as any to talk about the package in full. I
briefly mentioned it in the post about my research workflow, but I
figure now that the library has reached a state where I’m not ashamed of
it anymore—at least, not at the time of writing this—it may warrant its
own post.
Functionality§
Briefly,latex-change-env
can be seen as an extension of AUCTeX’s
built-in facilities to manipulate the current environment. Taking
functions like LaTeX-environment
as a base, it adds extra
functionality like deleting environments, changing to and from display
maths, “remembering” and editing labels, as well as macroAt least, macros taking exactly only argument, which is what
support is currently restricted to; contributions welcome!
and inline
maths support on top of them. There are two main “entry points”:
latex-change-env
and latex-change-env-cycle
.
The basic functionality may be used with a use-package
configuration
along the lines of
(use-package latex-change-env
:after latex
:commands latex-change-env
:bind (:map LaTeX-mode-map ("C-c r" . latex-change-env))
:custom
(latex-change-env-math-display '("\\[" . "\\]"))
(latex-change-env-math-inline '("$" . "$")))
latex-change-env
will pop up a selection
in the minibuffer; by default, one can delete the current
environmentIn the context of this package, by “environment” I will often mean
a proper environment, inline or display maths, or a (simple)
macro.
with k
, modify it into something else with m
, or
switch to display maths with d
. This is all controlled by the
latex-change-env-options
variable, allowing for user-defined functions
to be inserted, should that be desired.
For example, the following video showcases switching to display maths,
changing the environment into an equation
, and deleting it completely.
Cycling through environments§
Thelatex-change-env-cycle
function may be used to create a list of
environments to cycle through. For convenience, it depends on Omar
Antolín Camarena’s math-delimiters package, so as to facilitate a
comfortable workflow with maths environments out of the box.As such, be sure that you configure
and so on.
For
example, one could define a simple maths-based toggle
math-delimiters-{inline,display}
accordingly. For example, it may be useful to set
(setq math-delimiters-display
latex-change-env-math-display)
(defun my/insert-toggle-math ()
(interactive)
(latex-change-env-cycle
'(display-math equation* align* equation align)))
$
in latex-mode
. This works because
math-delimiters-insert
is called when one is not in any environment.
Quoting from the documentation of latex-change-env-cycle
(slightly
edited):
Cycle through the given list of environments. The special symbolThe following video illustrates howdisplay-math
denotes a display maths environment. If one is right at the end of a display or inline maths environment, callmath-delimiters-insert
instead of cycling through environments. The same is done when not inside any environment, which, for our definition of environment, also includes inline maths.
my/insert-toggle-math
might be
used.
Of course, cycling also works for non-maths environments, as well as macros; below, I bound the following to a key:
(defun my/cycle-macros ()
(interactive)
(latex-change-env-cycle
'(textbf emph textsc textit texttt)))
An effort was made to make macro handling feel like a first class citizen; for example, when cycling through possible modifications, instead of
LaTeX-environment-list-filtered
(as would be used for
environments), the macro-specific TeX--symbol-completion-table
is used
to generate a list of possible replacements.
Labels§
When changing or deleting environments,latex-change-env
tries to
smartly handle associated labels. In the former case, labels have a
unique prefix associated to what environment they are defined in; for
example, theorem
environments might start their labels with thm:
,
while a lemma
will have a lem:
prefix.This behaviour may be changed by customising the
Further, when deleting an
environment, or switching to one that does not have an associated label
prefix, the label is (i) deleted, and (ii) stored for the session, such
that it can be restored when switching back to the original environment.
While this is all well and good, renaming and deleting labels seems of
little use when the changes aren’t reflected in the rest of the project.
As such, there is an optional latex-change-env-labels
variable.latex-change-env-edit-labels-in-project
variable. When it is customised to t
, a label change/deletion
triggers a project-wide query-replace-regexp
, such that the user can
decide whether referencing labels should change as well. This utilises
Emacs’s own project.el
, so one should make sure that the LaTeX project
is version controlled—in which case the relevant ignore file is also
respected—or otherwise recognisable by the library.If you look closely at the video, you can see that, while the
label changes, the “Lemma” before the reference does not. This
would require more sophisticated regular expressions, but—reading
latex-change-env-labels
and making some assumptions—it certainly
seems possible to do.
Conclusion§
That’s about all of the functionality that the package currently has. It has certainly served me quite well so far—my hope is that it will be useful to at least one other person. On that note: contributions welcome! For example, something that should not be too hard to implement is the ability to store labels not just for the session, but permanently, by serialising the internal hash-map to a file. I don’t know how useful this would be but, given a certain workflow, it could certainly be worthwhile! Another path of inquiry might be to add better macro handling. As I said, support is currently limited to macros that take exactly one (mandatory) argument. However, the response one gets fromLaTeX-what-macro
is quite general, so I
reckon it wouldn’t be too hard to cook up a more general implementation.
Again, if you want to give the package a spin then you can find it on
GitLab, GitHub,
and melpa!