0

I have this code:

\author[p]{...}
\author[bc]{...}
\author[p]{...}
\author[l,o]{...}
\author[t,q]{...}
\author[at]{...}
\author[z]{...}
\author[ak]{...}
\author[az]{...}
\author[ah,bq]{...}

...

I want to replace all letters in square brackets with their corresponding numeric positions in alphabet, i.e.

a  --> 1
...
z  --> 26

aa --> 27
...
az --> 52

ba --> 53
...
bz --> 78
...

How can I do this replacement?

  • How big is the file? How many entries do you have to manipulate? Are all such entries surrounded by square brackets? Is there anything else that is surrounded by square brackets that should not be touched? What is the maximum number of letters in the [...] designation? Is this a one-off or is this something that you will do thousands of times? Just a few questions that would help frame any discsussion. As it is, the question is not particularly well specified. – NickD Jun 8 at 18:04
  • 2
    Emacs represents characters as integers, to a first approximation. So something like this should get you started: (defun (charpos c) (- c ?a)) – q.undertow Jun 8 at 22:48
  • @q.undertow I have tried your code, but it looks like to replace every char with its ascii integer representation, doesn't it? I need a replacement that it takes into account real position in alphabet (lexicographic orderin), so "aa" must be "27", "j" must be "10" and so on. In macros like \authors[...]{...} all letters in square brackets are not necessarily specified following alphabetical order. – Onner Irotsab Jun 9 at 7:43
  • @NickD Authors could be 100 or some thousand, but I think that "cz" could be a good limit. I need a function to be called in case of need, but there are no problems for that because I can write it by myself. Only I do not know how to do all above replacements. I will use narrow-to-region to bind that function to a specified region of my buffer, so no problems with other [...] in my LaTeX source. Second argument of \author does not have square brackets inside it. Square brackets are necessary to assign one or more letters to an author. – Onner Irotsab Jun 9 at 8:00
1

I have solved my problem using vectors. I have written two functions:

  • convert-letter-to-digit: it takes a letter as argument and give a numnber as output;
  • authors-letters-to-digits: call convert-letter-to-digit and replace letters with corresponding numbers.

To write convert-letter-to-digit I was inspiered to vectors in C language, so I have defined a vector with my letters in lexicographic order, i.e.

(setq v [a b c d e f g h i j k l m n o p q r s t u v w x y z
             aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az
             ba bb bc bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz
             ca cb cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz
             da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz
             ea eb ec ed ee ef eg eh ei ej ek el em en eo ep eq er es et eu ev ew ex ey ez])

My idea is to check if a given letter is equal to (aref v j), where j is from 0 to (length v). If it is true, j+1 is the position of my letter in v.

(defun convert-letter-to-digit (letter)
  (interactive "p")

  ;; define vector    
  (setq v [a b c d e f g h i j k l m n o p q r s t u v w x y z
             aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az
             ba bb bc bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz
             ca cb cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz
             da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz
             ea eb ec ed ee ef eg eh ei ej ek el em en eo ep eq er es et eu ev ew ex ey ez])

  ;; define cell-vector index
  (setq j 0)

  (while (< j (length v))

    ;; if letter is equal to j-th element in v, take j+1 as index
    (if (string= letter
                 (aref v j))
    (progn
      (setq index j)
      (setq index (+ index 1)))
      nil)
    (setq j (+ j 1)))
  index)

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

  ;; search "\author[...]{"    
  (goto-char (point-min))
  (while (re-search-forward "\\\\author\\[\\([^]]+\\)\\]{" nil t)
    (save-excursion

      ;; bind replacement inside "[...]"
      (setq pos1 (make-marker))
      (set-marker pos1 (+ (match-beginning 0) 8))
      (setq pos2 (make-marker))
      (set-marker pos2 (- (match-end 0) 2))

      ;; search and replace all letters with their corresponding indices
      (goto-char pos1)
      (while (re-search-forward "\\<\\([a-z]+\\)\\>" pos2 t)
    (replace-match (format "%s" (convert-letter-to-digit (match-string 0))))))))
| improve this answer | |

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.