I want to generalize this query-replace
regexp:
(perform-replace "Geophysical[\s\t\n]*Research[\s\t\n]*Letters"
"Geophys.\\\\ Res.\\\\ Lett."
t t nil 1 nil (point-min) (point-max))
that replaces "Geophysical Research Letters" with "Geophys.\ Res.\ Lett." in my LaTeX code,
with a function that I figured out to call later with mapcar
on a list of pairs of values.
I wrote this function:
(defun ExtendedJNameAbbreviator (COUPLE) ; 13/07/2017
(interactive)
(let* ((case-fold-search nil)
(ExtendedName (car COUPLE))
(ExtendedName (replace-regexp-in-string "[\s\t\n]"
"[\s\t\n]*" ExtendedName t))
(Abbreviation (nth 1 COUPLE))
(Abbreviation (replace-regexp-in-string "\\."
".\\\\\\\\" Abbreviation t)))
(perform-replace ExtendedName Abbreviation t t nil 1 nil (point-min) (point-max))
))
That works. You can test it with:
(setq mycouple '("Geophysical Research Letters"
"Geophys. Res. Lett."))
(ExtendedJNameAbbreviator mycouple)
But I don't understand "how it works". I mean why
(Abbreviation (replace-regexp-in-string "\\."
".\\\\\\\\" Abbreviation t)))
works? I tough it should be:
(Abbreviation (replace-regexp-in-string "\\."
".\\\\\\\\\\\\\\\\" Abbreviation t)))
instead if I put:
(read-string Abbreviation)
just before the perform-replace
line it return:
"Geophys.\\ Res.\\ Lett.\\"
Should't it be
"Geophys.\\\\ Res.\\\\ Lett.\\\\"
as the direct perform-replace
command?
More: I want to remove the last backslash in the replacement string. But if I wrote:
(defun ExtendedJNameAbbreviator (COUPLE) ; 13/07/2017
(interactive)
(let* ((case-fold-search nil)
(ExtendedName (car COUPLE))
(ExtendedName (replace-regexp-in-string "[\s\t\n]"
"[\s\t\n]*" ExtendedName t))
(Abbreviation (nth 1 COUPLE))
(Abbreviation (replace-regexp-in-string "\\."
".\\\\\\\\" Abbreviation t))
;; To remove last \ in replacement string:
(Abbreviation (replace-regexp-in-string "\\\\\\'"
"" Abbreviation t)))
(perform-replace ExtendedName Abbreviation t t nil 1 nil (point-min) (point-max))
))
I get
Invalid use of `\' in replacement text
I can't fix that. Do I need to set some string property? Do I miss something in the escaping logic? I think I don't understand the logic of the string sub-replacement in these cases.
Edit. Ok, I made it working but yet I cant understand why it works like that. This is the working code. (I realized that perform-replace
and replace-regexp-in-string
have slight differences in the rexexps management).
This is wy working code:
(defun ExtendedJNameAbbreviator (COUPLE) ; 13/07/2017
(interactive)
(let* ((case-fold-search nil)
(ExtendedName (car COUPLE))
(ExtendedName (replace-regexp-in-string "[\s\t\n]"
"[\s\t\n]*" ExtendedName t))
(Abbreviation (nth 1 COUPLE))
(Abbreviation (replace-regexp-in-string "\\."
".\\\\\\\\" Abbreviation t))
;; To remove last \ in replacement string:
(Abbreviation (replace-regexp-in-string "\\\\\\\\\\'"
"" Abbreviation t)))
(perform-replace ExtendedName Abbreviation t t nil 1 nil (point-min) (point-max))
))
perform-replace
reads "Don’t use this in your own program unless you want to query and set the mark just asquery-replace
does." It then gives you a suggestion for a loop to perform the replacements.