The default behaviour of C-c ) is to insert \ref and prefix it with~. I don't need the tilde after \S (i.e. I need the output to look like \S\ref{label}, rather than \S~\ref{label}). Is there a short code to insert into .emacs without copy pasting the whole reftex-reference function and adding exceptions there?

  • I didn't realize that \S was something specific: I thought it was a placeholder for a generic LaTeX construct. Maybe the thing to do is to let reftex do what it want to do and then fix it up at the end when the buffer is saved. Would that work for you or do you need it to happen when the \ref is inserted? – NickD Dec 12 '19 at 18:40
  • Yes, it will work, and very curious to know how this can be done. – Jabot Dec 12 '19 at 18:52

Here's a different answer along the lines of my comment: don't worry about what reftex inserts but clean up as you save the buffer. The idea is to use the before-save-hook to call a function that you define, just before the buffer is saved. The function will use the programmatic equivalent of replace-regexp to do the clean-up: it'll search for all occurrences of \S~\ref and replace each one by \S\ref. First, here's the function:

(defun jabot-cleanup ()
  (goto-char (buffer-end -1))
  (while (re-search-forward (regexp-quote "\\S~\\ref{"))
    (replace-match "\\S\\ref{" t t)))

The function goes to the beginning of the buffer and then searches for the pattern repeatedly until it gets to the end of the buffer. Each time the loop finds a match, it replaces it with the replacement text. Backslashes have to be escaped in strings, which is why they are doubled. There are a couple of subtle points here (the use of regexp-quote to simplify the search pattern, the use of optional arguments to replace-match to maintain the case of the original and to simplify the replacement pattern, ignoring narrowing complications...) that would take too long to explain. You will need to consult the documentation for all the hairy details.

Once you have a function (and you have tested it), then you can add it to the before-save-hook which will ensure that the function will be called when you say M-x save-buffer. The function will be called just before the buffer is written out to a file. There is also an after-save-hook (and many others in all parts of emacs: they are one very common way of customizing behavior) but we don't use it here.

To add the function to the hook, say:

(add-hook 'before-save-hook #'jabot-cleanup)

You can add both the definition of the function and the add-hook line to your .emacs if you want to make this permanent.

| improve this answer | |

reftex-reference inserts the string using the following piece of code:

         (if reftex-format-ref-function
             (funcall reftex-format-ref-function label form reftex-refstyle)
           (format form label label)))

So you can define your own reftex-format-ref-function to format the label any way you want. The doc string of reftex-format-ref-function says:

Function which produces the string to insert as a reference. Normally should be nil, because the format to insert a reference can already be specified in ‘reftex-label-alist’.

This hook also is used by the special commands to insert e.g. ‘\vref’ and ‘\fref’ references, so even if you set this, your setting will be ignored by the special commands.

The function will be called with three arguments, the LABEL, the DEFAULT FORMAT, which normally is ‘~\ref{%s}’ and the REFERENCE STYLE. The function should return the string to insert into the buffer.

Here's a very simple (and probably inadequate) function, but it may be enough to start with. The function just erases any ~ in the format, before using it to format the final output:

(setq reftex-format-ref-function
      (lambda (label fmt ref-style)
         (let ((fmt (replace-regexp-in-string "~" "" fmt)))
            (format fmt label label))))

You can add this to your .emacs (and if you don't like it or see strange results, you can delete it or comment it out and then restart your emacs - so you should probably test it in a separate session). Note that this is an anonymous function that is "assigned" to the variable reftex-format-ref-function. The reason for this is somewhat technical, so I'm not going to explain it here.

| improve this answer | |
  • My Lisp competence is really low, so do you have a ready-made code to insert in the .emacs file? Plus, I've already modified reftex-label-list, so will the new function ignore these modifications? – Jabot Dec 11 '19 at 20:04
  • I'm pretty sure that changes to reftex-label-alist (note the spelling) are taken care of at a higher level. The reftex-format-ref-function is a very low level operation: it just takes a bunch of inputs and spits out an output - it should probably not consult anything other than its arguments. – NickD Dec 12 '19 at 4:03
  • This works, but it omits tilde in every situation, whereas I only need to omit it after \S. I probably need to modify the function 'reftex-convert-string to add the exception there. How do I modify just this function? – Jabot Dec 12 '19 at 7:39
  • I didn't realize that \S was something specific: I thought it was a placeholder for a generic LaTeX construct. That seems to require context-sensitivity on the part of reftex-reference: I don't know enough about reftex to say whether it can be done easily (of course, it can be done, but it may be more difficult than it's worth). – NickD Dec 12 '19 at 18:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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