1

I need to replace below string:

(24.0000,28.0000) .. controls (27.3100,28.0000) and (29.9800,25.3100) .. (29.9800,22.0000)

to:

(12,14) .. controls (13.655,14) and (14.99,12.655) .. (14.99,11)

The rule is:

  1. coordinate x and y divided by 2.
  2. remove trailing zeros.
  3. other parts keep it as is.

I wish to do it in elisp:

#+BEGIN_SRC elisp :results output
  (let (str x y (i 0))
    (setq str "
  (24.0000,28.0000) .. controls (27.3100,28.0000) and (29.9800,25.3100) .. (29.9800,22.0000)
  ")
      (while (string-match "(\\([0-9.]+\\),\\([0-9.]+\\))"  str i)
        (setq i (match-end 0))
        (setq x (/ (string-to-number (match-string 1 str) 10) 2))
        (setq y (/ (string-to-number (match-string 2 str) 10) 2))
        (print (format "%f,%f" x  y))
        ))
#+END_SRC

#+RESULTS:
: 
: "12.000000,14.000000"
: 
: "13.655000,14.000000"
: 
: "14.990000,12.655000"
: 
: "14.990000,11.000000"

It can extract the numbers and do match on it, but how can I replace it within original string?

I am thinking about replace-regexp-in-string but it not good to do match on it.

  • Well... the problem is, floating point numbers are internally stored in base-two representation, so, when they are printed in base-ten representation, some "strange" things may happen, just like in this comic: knowyourmeme.com/photos/1070750-i-m-not-a-robot . As for the technicalities of replace-regexp-in-string - what was the problem? Your regex should match what you need, although it will match more than you need. Also note that the third argument to this function could be a function which performs arbitrary calculations to produce substituted string. – wvxvw Nov 16 '17 at 8:51
  • "trailing zero still not removed" - maybe try %.3g instead of %.3f? – npostavs Nov 16 '17 at 23:40
  • @npostavs Exactly, %.3g works. Thanks – lucky1928 Nov 17 '17 at 1:21
  • Please don't update your question with the answer but write your own answer. That makes sure that this question is listed as answered. Thanks, – Tobias Nov 17 '17 at 10:32
1

After read wvxvw and npostavs's comments, it's good to do it below:

#+BEGIN_SRC elisp :results value
  (defun my/rep(str)
    (let ((val "") x y)
      (when (string-match "\\([0-9.]+\\),\\([0-9.]+\\)" str)
        (setq x (/ (string-to-number (match-string 1 str) 10) 2))
        (setq y (/ (string-to-number (match-string 2 str) 10) 2))
        (setq val (format "%.3g,%.3g" x y)))
      val))

  (let (str x y (i 0))
    (setq str "
  (24.0000,28.0000) .. controls (27.3100,28.0000) and (29.9800,25.3100) .. (29.9800,22.0000)
  ")
    (print (replace-regexp-in-string "([0-9.]+,\.[0-9.]+)" 'my/rep str)))
#+END_SRC

#+RESULTS: latexdesc
: 
: (12,14) .. controls (13.7,14) and (15,12.7) .. (15,11)

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.