# How to replace first 100 digits with letters?

I want to replace the first 104 digits as it follows:

``````1    -->   a
...
26   -->   z
27   -->   aa
...
52   -->   az
53   -->   ba
...
104  -->   bz
``````

I have tried as it follows:

``````(defun digits-to-letters ()
(interactive)

(goto-char (point-min))

(save-excursion
(save-restriction
(narrow-to-region (search-forward "\\title" nil t)
(search-forward "\\abstract" nil t))

(goto-char (point-min))

(while (search-forward-regexp "\\([0-9]+\\)" nil t)
(setq digit (match-string 0))

;; 1-26 to a-z
(if (< digit 27)
(perform-replace digit
`((lambda (data count)
(string (+ (1- ?a) digit))))
t t nil 1 nil (point-min) (point-max))

;; 27-52 to aa-az
(if (and (> digit 26)
(< digit 53))
(perform-replace digit
`((lambda (data count)
(string (+ (1- ?a) (concat "a"
digit)))))
t t nil 1 nil (point-min) (point-max))

;; 53-104 to ba-bz
(if (and (> digit 52)
(< digit 105))
(perform-replace "\\([0-9]+\\)"
`((lambda (data count)
(string (+ (1- ?a) (concat "b"
digit)))))
t t nil 1 nil (point-min) (point-max))
)))
))))
``````

It gives me the following error:

``````Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p #("1" 0 1 (fontified t)))
``````

P.S. I have just asked something like this, but for the first 26 digits: How to replace a digit by a letter?.

There is a mistake in the correspodence between digits and letters:

``````53   -->  ba
...
78   -->  bz
79   -->  ca
...
104  -->  cz
``````

I have corrected my code as it follows:

``````(defun digits-to-letters ()
(interactive)

(goto-char (point-min))

(save-excursion
(save-restriction
(narrow-to-region (search-forward "\\title" nil t)
(search-forward "\\abstract" nil t))

(goto-char (point-min))

(while (search-forward-regexp "\\([0-9]+\\)" nil t)
(setq digit (string-to-number (match-string 0)))
(setq sdigit (match-string 0))

;; 1-26 to a-z
(if (< digit 27)
(replace-match (string (+ (1- ?a) digit)))

;; 27-52 to aa-az
(if (and (> digit 26)
(< digit 53))
(replace-match (concat
"a"
(string (+ (1- ?a) (- digit 26)))))

;; 53-78 to ba-bz
(if (and (> digit 52)
(< digit 79))
(replace-match (concat
"b"
(string (+ (1- ?a) (- digit 52)))))

;; 79-104 to ba-bz
(if (and (> digit 78)
(< digit 105))
(replace-match (concat
"c"
(string (+ (1- ?a) (- digit 78)))))

))))

))))
``````

Now it works.

• You set `digit` to `(match-string 0)` and compare that string in `(< digit 27)` with a number. Maybe you want to use `(setq digit (string-to-number (match-string 0)))`. Do you really want to use `perform-replace`? You also use `digit` later on as string to replace. So you need both the numeric value and the string. Maybe introduce one more variable for that. – Tobias Feb 11 at 17:14
• The error message says that your code expected a number or marker but was passed a (propertized) string with a single character, instead. Chars are the same as integers - it's probably a character that the code expected, and you passed it a string with that char, instead. – Drew Feb 11 at 18:56

104 would be cz I think.

Using org mode eval setup:-- I suspect there are better choices fr functions but I'm an elisp learner.

These conversions might be more appropriates in your code in that there's less if/thens based on ranges.

``````#+begin_src emacs-lisp

(setq c 104)
(setq lsc (char-to-string (+ (% (- c 1) 26) (string-to-char "a"))))
(setq msc (char-to-string (- (+ (/ (- c 1) 26) (string-to-char "a")) 1)))
(concat msc lsc)
#+end_src

#+RESULTS:
: cz
``````

Tidy to your desires. I didnt check for <27 so single digit but your framework does.

You can use `org-number-to-letter` from `org-table.el` (requires at least Emacs 26.1 or Org 9.1.9?)

``````(require 'org-table)

(org-number-to-letters 26)
;; => "Z"

(org-number-to-letters 52)
;; => "AZ"
``````

And type `C-M-%` (`query-replace-regexp`) with

``````[0-9]+ → \,(org-number-to-letters \#&)
``````

If you need to do the search-and-replace from Lisp, use `re-search-forward` and `replace-match` instead, don't use `perform-replace`:

``````(while (re-search-forward "[0-9]+" nil t)
(replace-match
(org-number-to-letters
(string-to-number (match-string 0)))))
``````

or `replace-regexp-in-string`:

``````(replace-regexp-in-string
(rx (1+ num))
(lambda (s)
(org-number-to-letters
(string-to-number s)))
"Hello, 731!")
;; => "Hello, ABC!"
``````