0

It must be something obvious but I cannot find information on this issue.

When reftex-mode is enabled, I can type ~C-c )~ and for the following piece of code

\begin{equation}
2x=4
\label{Eq:A}
\end{equation}
 
\begin{equation}
a=b
\label{Eq:B}
\end{equation}

a pretty list of labelled blocks is generated (label + equation formula), so I can easily navigate and choose the right label to insert.

How can I achieve similar functionality when working in org-mode approach? I'd like to get all #+NAME tags in the document when labeling equations as follows:

 #+NAME: Eq:simpleEq
 \begin{equation}
 2x=4
 \end{equation}

 #+NAME: Eq:simplerEq
 \begin{equation}
 a=b
 \end{equation}

I don't expect the solution to be as comfortable as in ~reftex-mode~. Well, it'd be perfect if someone provided it, but simple list of all +NAME tags would do... ;)

1 Answer 1

1

You can use org-element-map to apply a function that gets the #+NAME of each matched element. Here's a function that does that:

#+begin_src elisp
  (defun my/get-name (e)
    (org-element-property :name e))

  (defun my/latex-environment-names ()
    (org-element-map (org-element-parse-buffer) 'latex-environment #'my/get-name))

#+end_src

We parse the whole buffer, select the latex-environment elements and map over them the function my/get-name which gets the name of each such environment, accumulating them into a list and returning that.

You call it with M-: (my/latex-environment-names). But you probably want to write a wrapper command that calls it and deals with the list of names however it wants to. Here's a simple-minded example of that:

#+begin_src elisp
  (defun my/report-latex-environment-names ()
    (interactive)
    (message (format "%S" (my/latex-environment-names))))

  (define-key org-mode-map (kbd "C-c z") #'my/report-latex-environment-names)
#+end_src

Then C-c z will invoke the report function which will print the result of my/latex-environment-names in the echo area.


Here is the enhanced version as requested in a comment. Given the hint, I found out that the :value property holds the text of the environment, so we need to do some string manipulations to get only the part we want. string-split splits the string on newlines (\n) and returns the lines as a list; we then use nth to get the equation which is the second element of the list (remember, nth starts numbering the elements of the list from 0), and string-trim trims off leading and trailing whitespace. We call both the name and the value function at each matching element and we concatenate the results into a single string. Overall, it's very similar to the code block above:

#+begin_src elisp
  (defun my/get-name (e)
    (org-element-property :name e))

  (defun my/get-value (e)
    (string-trim (nth 1 (string-split (org-element-property :value e) "\n"))))

  (defun my/get-both (e)
    (concat (my/get-name e) " " (my/get-value e)))
  
  (defun my/latex-environment-names-values ()
    (org-element-map (org-element-parse-buffer) 'latex-environment #'my/get-both))

#+end_src
3
  • Thanks. I just needed to change keybinding in order to avoid sequence starts with non-prefix key error (this probably has something to do with this), but anyway, it works as required. Wouldn't it be too much if I asked you to extend the code (or at least, give a hint how to do this) to display the name of the equation next to the equation itself? (In the example above it would be Eq:simpleEq 2x=4 RET Eq:simplerEq a=b) May 24, 2023 at 9:18
  • Yes, the keybinding is arbitrary: C-c z is (usually) undefined so I tend to use it as an example - you should use your own keybinding (interesting link BTW - thanks! I take it you use emacspeak then?). As for the RFE, it should not be too hard except for one problem: in your case the body of the environment is the single equation, but in general there may be many lines (either of a single equation or many equations or other things). What do you want to do in that case? Is the first line of the body of the equation environment enough? If I find some time, I'll try to add the enhancement...
    – NickD
    May 24, 2023 at 15:31
  • ... but no promises. You might try it yourself, mimicking the code above. Go to the beginning of the equation environment (the backslash of \begin) and type M-: (org-element-at-point). The value of that is the parse tree of the element: see if you can figure out how to get the text using org-element-property and then manipulate the text (it's just a string so you can use the elisp string functions or perhaps the enhanced ones in s.el - available from MELPA) until you get just the part you want.
    – NickD
    May 24, 2023 at 15:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.