unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* How modify numbers in a region by a multiplier?
@ 2010-07-01 13:55 Seweryn Kokot
  2010-07-01 14:16 ` Juanma Barranquero
                   ` (3 more replies)
  0 siblings, 4 replies; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-01 13:55 UTC (permalink / raw)
  To: help-gnu-emacs

Hi,

I would like to modify numbers in a region/buffer by a given multiplier.

Imagine that I have some numbers

33.444 3333 4433.4443 3344 .34234

and I want them multiplied for example by 0.1

to receive

3.3444 333.3 443.34443 334.4 .034234

I tried with this function I wrote, but it doesn't work properly.
Any idea why?

(defun my-multiply-numbers-in-region-or-buffer (multiplier)
  (interactive "nGive multiplier: ")
  (let (beg end object)
	(if (use-region-p)
        (progn
          (setq object "region")
          (setq beg (region-beginning))
          (setq end (region-end)))
      (setq object "buffer")
      (setq beg (point-min))
      (setq end (point-max)))
	(goto-char beg)
	(while (re-search-forward "\\([0-9]*\\.?[0-9]*\\)" end t)
	  (replace-match (format "%.3f" (* (string-to-number (match-string 1)) 
multiplier))))
	(message "Numbers in %s modified by multiplier %s." object 
multiplier)))




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 13:55 Seweryn Kokot
@ 2010-07-01 14:16 ` Juanma Barranquero
  2010-07-01 14:31   ` Seweryn Kokot
  2010-07-01 15:01   ` Dan Davison
       [not found] ` <mailman.0.1277993821.20412.help-gnu-emacs@gnu.org>
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-01 14:16 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

On Thu, Jul 1, 2010 at 15:55, Seweryn Kokot <sewkokot@gmail.com> wrote:

> Imagine that I have some numbers
>
> 33.444 3333 4433.4443 3344 .34234
>
> and I want them multiplied for example by 0.1
>
> to receive
>
> 3.3444 333.3 443.34443 334.4 .034234

Interactively, you can try with some variation of

M-x replace-regexp \([0-9.]+\) <RET> \,(/ (string-to-number \1) 10.0) <RET>

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
       [not found] ` <mailman.0.1277993821.20412.help-gnu-emacs@gnu.org>
@ 2010-07-01 14:19   ` David Kastrup
  0 siblings, 0 replies; 28+ messages in thread
From: David Kastrup @ 2010-07-01 14:19 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu@gmail.com> writes:

> On Thu, Jul 1, 2010 at 15:55, Seweryn Kokot <sewkokot@gmail.com> wrote:
>
>> Imagine that I have some numbers
>>
>> 33.444 3333 4433.4443 3344 .34234
>>
>> and I want them multiplied for example by 0.1
>>
>> to receive
>>
>> 3.3444 333.3 443.34443 334.4 .034234
>
> Interactively, you can try with some variation of
>
> M-x replace-regexp \([0-9.]+\) <RET> \,(/ (string-to-number \1) 10.0) <RET>

(string-to-number \1) is overly verbose for \#1

-- 
David Kastrup


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
       [not found] <mailman.0.1277992530.1006.help-gnu-emacs@gnu.org>
@ 2010-07-01 14:19 ` Marc Mientki
  2010-07-01 15:55 ` Andreas Politz
  1 sibling, 0 replies; 28+ messages in thread
From: Marc Mientki @ 2010-07-01 14:19 UTC (permalink / raw)
  To: help-gnu-emacs

Am 01.07.2010 15:55, schrieb Seweryn Kokot:
 > Hi,
 >
 > I would like to modify numbers in a region/buffer by a given multiplier.
 >
 > Imagine that I have some numbers
 >
 > 33.444 3333 4433.4443 3344 .34234
 >
 > and I want them multiplied for example by 0.1
 >
 > to receive
 >
 > 3.3444 333.3 443.34443 334.4 .034234
 >
 > I tried with this function I wrote, but it doesn't work properly.
 > Any idea why?
 >
 > (defun my-multiply-numbers-in-region-or-buffer (multiplier)
 >    (interactive "nGive multiplier: ")
 >    (let (beg end object)
 > 	(if (use-region-p)
 >          (progn
 >            (setq object "region")
 >            (setq beg (region-beginning))
 >            (setq end (region-end)))
 >        (setq object "buffer")
 >        (setq beg (point-min))
 >        (setq end (point-max)))
 > 	(goto-char beg)
 > 	(while (re-search-forward "\\([0-9]*\\.?[0-9]*\\)" end t)
 > 	  (replace-match (format "%.3f" (* (string-to-number (match-string 1))
 > multiplier))))
 > 	(message "Numbers in %s modified by multiplier %s." object
 > multiplier)))
 >
 >

I use for such purposes macro-math.el from Nikolaj Schumacher
(http://nschum.de/src/emacs/macro-math/) and bind so:

(global-set-key "\C-x~" 'macro-math-eval-and-round-region)
(global-set-key "\C-x=" 'macro-math-eval-region)

The next step is to write macro where you search begin of the numer and
set there mark at this position, then go to the end of the number (don't
worry that mark disapear - it is still there) and type mathematical
operation - in your case *0.1 - and call macro-math-eval-region with
C-x= which replace all marked text (original number and '*0.1') with the
results of the operation. When you don't wish to replace text call
macro-math-eval-region with C-u prefix. In this case the result will be
written to kill-ring and yiu can yank it on other place.

This is a very simple example of macro for your task:
(fset 'mult-by-0.1
    [?\C-  ?\C-s ?  ?\C-m left ?* ?0 ?. ?1 ?\C-x ?= ?\C-f])


HTH
regards
Marc





^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 14:16 ` Juanma Barranquero
@ 2010-07-01 14:31   ` Seweryn Kokot
  2010-07-01 15:56     ` Juanma Barranquero
  2010-07-01 15:01   ` Dan Davison
  1 sibling, 1 reply; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-01 14:31 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu <at> gmail.com> writes:

> Interactively, you can try with some variation of
> 
> M-x replace-regexp \([0-9.]+\) <RET> \,(/ (string-to-number \1) 10.0) <RET>


Thank you it works! But why my function does not work since re-search-forward 
and replace-match is recommended in lisp functions?





^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 14:16 ` Juanma Barranquero
  2010-07-01 14:31   ` Seweryn Kokot
@ 2010-07-01 15:01   ` Dan Davison
  2010-07-01 20:16     ` Seweryn Kokot
  1 sibling, 1 reply; 28+ messages in thread
From: Dan Davison @ 2010-07-01 15:01 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: Seweryn Kokot, help-gnu-emacs

Juanma Barranquero <lekktu@gmail.com> writes:

> On Thu, Jul 1, 2010 at 15:55, Seweryn Kokot <sewkokot@gmail.com> wrote:
>
>> Imagine that I have some numbers
>>
>> 33.444 3333 4433.4443 3344 .34234
>>
>> and I want them multiplied for example by 0.1
>>
>> to receive
>>
>> 3.3444 333.3 443.34443 334.4 .034234

Here are three solutions using Org-mode.

* Using the Org spreadsheet
http://orgmode.org/org.html#The-spreadsheet
http://orgmode.org/worg/org-tutorials/org-spreadsheet-intro.php

Leave second column blank; issue C-u C-c C-c with point in the table 

|    33.444 |    3.3444 |
|      3333 |     333.3 |
| 4433.4443 | 443.34443 |
|      3344 |     334.4 |
|   0.34234 |  0.034234 |
#+tblfm: $2=$1*0.1


* Using Org-babel
http://orgmode.org/worg/org-contrib/babel/index.php
Unless using Org from git it's in the Org contrib directory; Org-babel
is integrated into Org in the git HEAD and so in the next Org release,
with a new manual chapter.

Use C-c C-c on the source code blocks to generate the results tables.

#+tblname: tab
| 33.444 | 3333 | 4433.4443 | 3344 | .34234 |

** Using emacs lisp

#+begin_src emacs-lisp :var X=tab
(mapcar (lambda (x) (* 0.1 x)) (car X))
#+end_src

#+results:
| 3.3444000000000003 | 333.3 | 443.34443000000005 | 334.40000000000003 | 0.034234 |

** Using R
#+begin_src R :var X=tab
X * 0.1
#+end_src

#+results:
| 3.3444 | 333.3 | 443.34443 | 334.4 | 0.034234 |


Dan


>
> Interactively, you can try with some variation of
>
> M-x replace-regexp \([0-9.]+\) <RET> \,(/ (string-to-number \1) 10.0) <RET>
>
>     Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
       [not found] <mailman.0.1277992530.1006.help-gnu-emacs@gnu.org>
  2010-07-01 14:19 ` How modify numbers in a region by a multiplier? Marc Mientki
@ 2010-07-01 15:55 ` Andreas Politz
  2010-07-01 16:45   ` Pascal J. Bourguignon
  1 sibling, 1 reply; 28+ messages in thread
From: Andreas Politz @ 2010-07-01 15:55 UTC (permalink / raw)
  To: help-gnu-emacs

Seweryn Kokot <sewkokot@gmail.com> writes:

> Hi,
>
> I would like to modify numbers in a region/buffer by a given multiplier.
>
> Imagine that I have some numbers
>
> 33.444 3333 4433.4443 3344 .34234
>
> and I want them multiplied for example by 0.1
>
> to receive
>
> 3.3444 333.3 443.34443 334.4 .034234
>
> I tried with this function I wrote, but it doesn't work properly.
> Any idea why?
>
> (defun my-multiply-numbers-in-region-or-buffer (multiplier)
>   (interactive "nGive multiplier: ")
>   (let (beg end object)
> 	(if (use-region-p)
>         (progn
>           (setq object "region")
>           (setq beg (region-beginning))
>           (setq end (region-end)))
>       (setq object "buffer")
>       (setq beg (point-min))
>       (setq end (point-max)))
> 	(goto-char beg)
> 	(while (re-search-forward "\\([0-9]*\\.?[0-9]*\\)" end t)
> 	  (replace-match (format "%.3f" (* (string-to-number (match-string 1)) 
> multiplier))))
> 	(message "Numbers in %s modified by multiplier %s." object 
> multiplier)))

The problem is that your regexp matches the empty word.

-ap


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 14:31   ` Seweryn Kokot
@ 2010-07-01 15:56     ` Juanma Barranquero
  2010-07-01 20:10       ` Seweryn Kokot
  0 siblings, 1 reply; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-01 15:56 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

On Thu, Jul 1, 2010 at 16:31, Seweryn Kokot <sewkokot@gmail.com> wrote:

> But why my function does not work since re-search-forward
> and replace-match is recommended in lisp functions?

The regexp you use to match the numbers

  "\\([0-9]*\\.?[0-9]*\\)"

matches also the empty string, so after 33.444 it matches on "" and
generates .000, and then matches again on "" and generates another
.000, etc.

I just used "\\([0-9.]+\\)", which is less precise (it'll match
"1..2", ".", ".3.", etc.), but for quick-and-dirty jobs is enough.
You'll have to fix your regexp, or move point one character forward if
you matched the empty string.

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 15:55 ` Andreas Politz
@ 2010-07-01 16:45   ` Pascal J. Bourguignon
  0 siblings, 0 replies; 28+ messages in thread
From: Pascal J. Bourguignon @ 2010-07-01 16:45 UTC (permalink / raw)
  To: help-gnu-emacs

Andreas Politz <politza@fh-trier.de> writes:

> Seweryn Kokot <sewkokot@gmail.com> writes:
>
>> Hi,
>>
>> I would like to modify numbers in a region/buffer by a given multiplier.
>>
>> Imagine that I have some numbers
>>
>> 33.444 3333 4433.4443 3344 .34234
>>
>> and I want them multiplied for example by 0.1
>>
>> to receive
>>
>> 3.3444 333.3 443.34443 334.4 .034234
>>
>> I tried with this function I wrote, but it doesn't work properly.
>> Any idea why?
>>
>> (defun my-multiply-numbers-in-region-or-buffer (multiplier)
>>   (interactive "nGive multiplier: ")
>>   (let (beg end object)
>> 	(if (use-region-p)
>>         (progn
>>           (setq object "region")
>>           (setq beg (region-beginning))
>>           (setq end (region-end)))
>>       (setq object "buffer")
>>       (setq beg (point-min))
>>       (setq end (point-max)))
>> 	(goto-char beg)
>> 	(while (re-search-forward "\\([0-9]*\\.?[0-9]*\\)" end t)
>> 	  (replace-match (format "%.3f" (* (string-to-number (match-string 1)) 
>> multiplier))))
>> 	(message "Numbers in %s modified by multiplier %s." object 
>> multiplier)))
>
> The problem is that your regexp matches the empty word.

Or said otherwise:

    Some people, when confronted with a problem, think "I know, I'll
    use regular expressions." Now they have two problems. 

                -- Jamie Zawinski

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 13:55 Seweryn Kokot
  2010-07-01 14:16 ` Juanma Barranquero
       [not found] ` <mailman.0.1277993821.20412.help-gnu-emacs@gnu.org>
@ 2010-07-01 16:54 ` Qiang Guo
       [not found] ` <mailman.1.1278003297.20718.help-gnu-emacs@gnu.org>
  3 siblings, 0 replies; 28+ messages in thread
From: Qiang Guo @ 2010-07-01 16:54 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

At Thu, 1 Jul 2010 13:55:11 +0000 (UTC),
Seweryn Kokot wrote:
> 
> Hi,
> 
> I would like to modify numbers in a region/buffer by a given multiplier.
> 
> Imagine that I have some numbers
> 
> 33.444 3333 4433.4443 3344 .34234
> 
> and I want them multiplied for example by 0.1
> 
> to receive
> 
> 3.3444 333.3 443.34443 334.4 .034234
> 
> I tried with this function I wrote, but it doesn't work properly.
> Any idea why?
> 
> (defun my-multiply-numbers-in-region-or-buffer (multiplier)
>   (interactive "nGive multiplier: ")
>   (let (beg end object)
> 	(if (use-region-p)
>         (progn
>           (setq object "region")
>           (setq beg (region-beginning))
>           (setq end (region-end)))
>       (setq object "buffer")
>       (setq beg (point-min))
>       (setq end (point-max)))
> 	(goto-char beg)
> 	(while (re-search-forward "\\([0-9]*\\.?[0-9]*\\)" end t)
> 	  (replace-match (format "%.3f" (* (string-to-number (match-string 1)) 
> multiplier))))
> 	(message "Numbers in %s modified by multiplier %s." object 
> multiplier)))
> 
> 



Hi,

The problem is the re-search-forward. It should be
dynamically changed according to the replace events, since
the (point) would exceed the variable end after replacement.

Qiang 



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
       [not found] ` <mailman.1.1278003297.20718.help-gnu-emacs@gnu.org>
@ 2010-07-01 18:54   ` Pascal J. Bourguignon
  0 siblings, 0 replies; 28+ messages in thread
From: Pascal J. Bourguignon @ 2010-07-01 18:54 UTC (permalink / raw)
  To: help-gnu-emacs

Qiang Guo <mcknight0219@gmail.com> writes:

> At Thu, 1 Jul 2010 13:55:11 +0000 (UTC),
> Seweryn Kokot wrote:
>> 
>> Hi,
>> 
>> I would like to modify numbers in a region/buffer by a given multiplier.
>> 
>> Imagine that I have some numbers
>> 
>> 33.444 3333 4433.4443 3344 .34234
>> 
>> and I want them multiplied for example by 0.1
>> 
>> to receive
>> 
>> 3.3444 333.3 443.34443 334.4 .034234
>> 
>> I tried with this function I wrote, but it doesn't work properly.
>> Any idea why?
>> 
>> (defun my-multiply-numbers-in-region-or-buffer (multiplier)
>>   (interactive "nGive multiplier: ")
>>   (let (beg end object)
>> 	(if (use-region-p)
>>         (progn
>>           (setq object "region")
>>           (setq beg (region-beginning))
>>           (setq end (region-end)))
>>       (setq object "buffer")
>>       (setq beg (point-min))
>>       (setq end (point-max)))
>> 	(goto-char beg)
>> 	(while (re-search-forward "\\([0-9]*\\.?[0-9]*\\)" end t)
>> 	  (replace-match (format "%.3f" (* (string-to-number (match-string 1)) 
>> multiplier))))
>> 	(message "Numbers in %s modified by multiplier %s." object 
>> multiplier)))
>> 
>> 
>
>
>
> Hi,
>
> The problem is the re-search-forward. It should be
> dynamically changed according to the replace events, since
> the (point) would exceed the variable end after replacement.

Obviously NOT!

The point is a marker, not an integer.


(with-temp-buffer 
  (insert "aaa-bbb-ccc")
  (goto-char 0)
  (when (re-search-forward "\\(b+\\)")
    (replace-match "xxxxxx")
    (insert "|"))
  (buffer-substring (point-min) (point-max)))

--> "aaa-xxxxxx|-ccc"



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 15:56     ` Juanma Barranquero
@ 2010-07-01 20:10       ` Seweryn Kokot
  2010-07-01 20:16         ` Juanma Barranquero
  0 siblings, 1 reply; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-01 20:10 UTC (permalink / raw)
  To: help-gnu-emacs

Indeed, your regexp used with my function works too. So as you wrote, for my
purpose it's more than enough :-)





^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 15:01   ` Dan Davison
@ 2010-07-01 20:16     ` Seweryn Kokot
  0 siblings, 0 replies; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-01 20:16 UTC (permalink / raw)
  To: help-gnu-emacs

Dan Davison <davison <at> stats.ox.ac.uk> writes:

> Here are three solutions using Org-mode.
> 
> * Using the Org spreadsheet
> http://orgmode.org/org.html#The-spreadsheet
> http://orgmode.org/worg/org-tutorials/org-spreadsheet-intro.php
> 
> Leave second column blank; issue C-u C-c C-c with point in the table 
> 
> |    33.444 |    3.3444 |
> |      3333 |     333.3 |
> | 4433.4443 | 443.34443 |
> |      3344 |     334.4 |
> |   0.34234 |  0.034234 |
> #+tblfm: $2=$1*0.1
> 
> * Using Org-babel...
> ** Using emacs lisp...
> ** Using R...

Thank you for help, however my purpose writing this function was to make it more
easy to type many tedious floating point numbers. So I thought it would be
better to write integers and then multiply them by 0.001 or whatever. In this
way I could never type "." in numbers and after the work done just use this
function to do it for me.








^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 20:10       ` Seweryn Kokot
@ 2010-07-01 20:16         ` Juanma Barranquero
  2010-07-01 20:36           ` Seweryn Kokot
       [not found]           ` <mailman.2.1278016589.8594.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-01 20:16 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

On Thu, Jul 1, 2010 at 22:10, Seweryn Kokot <sewkokot@gmail.com> wrote:

> Indeed, your regexp used with my function works too. So as you wrote, for my
> purpose it's more than enough :-)

Qiang Guo is right, though, in pointing that you're using a fixed
`end' but the buffer or region length is potentially changing with
every replace.

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 20:16         ` Juanma Barranquero
@ 2010-07-01 20:36           ` Seweryn Kokot
  2010-07-01 22:38             ` Juanma Barranquero
       [not found]           ` <mailman.2.1278016589.8594.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-01 20:36 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu <at> gmail.com> writes:

> Qiang Guo is right, though, in pointing that you're using a fixed
> `end' but the buffer or region length is potentially changing with
> every replace.

Is there a canonical solution to this problem, since it seems that it should
happen frequently when using the following structure: 
(while (re-search-forward "\\([0-9.]+\\)" end t)
(replace-match (format "%.2f" (* (string-to-number (match-string 1))
multiplier))))

I tried this in a buffer with just "1 4 5 5 4 5 4" and specifying 
the multiplier of 0.001 gives
Debugger entered--Lisp error: (error "Invalid search 
bound (wrong side of point)")
  re-search-forward("\\([0-9.]+\\)" 14 t) ...

or modifies only a part of the buffer if the content of 
the buffer is "1 4 5 5 4 5 4 " (just adding one space). 
Then using my function gives

0.00 0.00 0.01 5 4 5 4 

P.S. The function now is as follows:

(defun my-multiply-numbers-in-region-or-buffer (multiplier)
  (interactive "nSpecify a multiplier (default is 0.001): ")
;; if nil - RET multiplier is 0.001
  (let (beg end object)
	(if (use-region-p)
        (progn
          (setq object "region")
          (setq beg (region-beginning))
          (setq end (region-end)))
      (setq object "buffer")
      (setq beg (point-min))
      (setq end (point-max)))
	(unless multiplier
	  (setq multiplier 0.001))
	(goto-char beg)
	(while (re-search-forward "\\([0-9.]+\\)" end t)
	  (replace-match (format "%.2f" (* (string-to-number (match-string 1))
multiplier))))
	(message "Numbers in %s modified by multiplier %s." object multiplier)))




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
       [not found]           ` <mailman.2.1278016589.8594.help-gnu-emacs@gnu.org>
@ 2010-07-01 20:42             ` David Kastrup
  2010-07-01 21:03             ` Andreas Politz
  1 sibling, 0 replies; 28+ messages in thread
From: David Kastrup @ 2010-07-01 20:42 UTC (permalink / raw)
  To: help-gnu-emacs

Seweryn Kokot <sewkokot@gmail.com> writes:

> Juanma Barranquero <lekktu <at> gmail.com> writes:
>
>> Qiang Guo is right, though, in pointing that you're using a fixed
>> `end' but the buffer or region length is potentially changing with
>> every replace.
>
> Is there a canonical solution to this problem, since it seems that it should
> happen frequently when using the following structure: 
> (while (re-search-forward "\\([0-9.]+\\)" end t)
> (replace-match (format "%.2f" (* (string-to-number (match-string 1))
> multiplier))))

Probably easiest to do

(save-restriction
  (narrow-to-region start end
     ...

-- 
David Kastrup


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
       [not found]           ` <mailman.2.1278016589.8594.help-gnu-emacs@gnu.org>
  2010-07-01 20:42             ` David Kastrup
@ 2010-07-01 21:03             ` Andreas Politz
  1 sibling, 0 replies; 28+ messages in thread
From: Andreas Politz @ 2010-07-01 21:03 UTC (permalink / raw)
  To: help-gnu-emacs

Seweryn Kokot <sewkokot@gmail.com> writes:

> Juanma Barranquero <lekktu <at> gmail.com> writes:
>
>> Qiang Guo is right, though, in pointing that you're using a fixed
>> `end' but the buffer or region length is potentially changing with
>> every replace.
>
> Is there a canonical solution to this problem, since it seems that it should
> happen frequently when using the following structure: 
> (while (re-search-forward "\\([0-9.]+\\)" end t)
> (replace-match (format "%.2f" (* (string-to-number (match-string 1))
> multiplier))))
>

Yes, use a marker.

(defun my-multiply-numbers-in-region-or-buffer (multiplier beg end)
  (interactive
   (cons (read-number "Specify a multiplier: " 0.001)
         (if (use-region-p) (list (region-beginning) (region-end))
           (list (point-min) (point-max)))))
  (goto-char beg)
  (let ((end (copy-marker end)))
    (while (re-search-forward "\\([0-9.]+\\)" end t)
      (replace-match (format "%.2f"
                             (* (string-to-number (match-string 1))
                                multiplier)))))
  (when (interactive-p)
    (message "Numbers in %s modified by multiplier %s."
             (if (use-region-p) "region" "buffer")
             multiplier)))


-ap


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 20:36           ` Seweryn Kokot
@ 2010-07-01 22:38             ` Juanma Barranquero
  2010-07-02  6:41               ` Seweryn Kokot
  0 siblings, 1 reply; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-01 22:38 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

On Thu, Jul 1, 2010 at 22:36, Seweryn Kokot <sewkokot@gmail.com> wrote:

> Is there a canonical solution to this problem, since it seems that it should
> happen frequently when using the following structure:

Try using a marker instead of just the number value of `point'.

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-01 22:38             ` Juanma Barranquero
@ 2010-07-02  6:41               ` Seweryn Kokot
  2010-07-02  9:33                 ` Juanma Barranquero
  0 siblings, 1 reply; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-02  6:41 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu <at> gmail.com> writes:

> 
> Try using a marker instead of just the number value of `point'.
 
Good hint, now it seems ok! For interested see the current function

(defun my-multiply-numbers-in-region-or-buffer (multiplier)
  (interactive "nSpecify a multiplier (default is 0.001): ")
;; if nil - RET multiplier is 0.001
  (let (beg end object end-mark)
	(if (use-region-p)
        (progn
          (setq object "region")
          (setq beg (region-beginning))
          (setq end (region-end)))
      (setq object "buffer")
      (setq beg (point-min))
      (setq end (point-max)))
	(setq end-mark (copy-marker end))
	(unless multiplier
	  (setq multiplier 0.001))
	(goto-char beg)
;	(while (re-search-forward "\\([0-9.]+\\)" end t)
	(while (re-search-forward "\\([0-9.]+\\)" (marker-position end-mark) t)
	  (replace-match (format "%.2f" (* (string-to-number (match-string 1)) 
multiplier))))
	(message "Numbers in %s modified by multiplier %s." object 
multiplier)))




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-02  6:41               ` Seweryn Kokot
@ 2010-07-02  9:33                 ` Juanma Barranquero
  2010-07-02  9:53                   ` Seweryn Kokot
  0 siblings, 1 reply; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-02  9:33 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

On Fri, Jul 2, 2010 at 08:41, Seweryn Kokot <sewkokot@gmail.com> wrote:

>      (setq end (point-max)))
>        (setq end-mark (copy-marker end))

There's `point-max-marker'.

>        (while (re-search-forward "\\([0-9.]+\\)" (marker-position end-mark) t)

In many cases, you can pass a marker to an Emacs primitive as if it
were a number; i.e.,

>        (while (re-search-forward "\\([0-9.]+\\)" end-mark t)

should work.

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-02  9:33                 ` Juanma Barranquero
@ 2010-07-02  9:53                   ` Seweryn Kokot
  2010-07-02 10:05                     ` Juanma Barranquero
  0 siblings, 1 reply; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-02  9:53 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu <at> gmail.com> writes:


> >      (setq end (point-max)))
> >        (setq end-mark (copy-marker end))
> 
> There's `point-max-marker'.

does it work also for regions? Because I use this function for buffers as well 
as for regions if selected.

> 
> In many cases, you can pass a marker to an Emacs primitive as if it
> were a number; i.e.,
> 
> >        (while (re-search-forward "\\([0-9.]+\\)" end-mark t)
> 
> should work.
> 

good to know,
Thank you Juanma.





^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-02  9:53                   ` Seweryn Kokot
@ 2010-07-02 10:05                     ` Juanma Barranquero
  2010-07-02 18:15                       ` Štěpán Němec
  0 siblings, 1 reply; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-02 10:05 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

On Fri, Jul 2, 2010 at 11:53, Seweryn Kokot <sewkokot@gmail.com> wrote:

> does it work also for regions? Because I use this function for buffers as well
> as for regions if selected.

Yes. Compare the docstrings of `point-max' and `point-max-marker'.

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-02 10:05                     ` Juanma Barranquero
@ 2010-07-02 18:15                       ` Štěpán Němec
  2010-07-02 20:30                         ` Juanma Barranquero
  0 siblings, 1 reply; 28+ messages in thread
From: Štěpán Němec @ 2010-07-02 18:15 UTC (permalink / raw)
  To: Juanma Barranquero; +Cc: Seweryn Kokot, help-gnu-emacs

Juanma Barranquero <lekktu@gmail.com> writes:

> On Fri, Jul 2, 2010 at 11:53, Seweryn Kokot <sewkokot@gmail.com> wrote:
>
>> does it work also for regions? Because I use this function for buffers as
> well
>> as for regions if selected.
>
> Yes. Compare the docstrings of `point-max' and `point-max-marker'.

I see nothing in the docstrings that would suggest that (unless you use
`narrow-to-region', obviously -- which the original function discussed
in this thread did *not* use, although it would have been the right
thing to do IIRC).

Štěpán



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-02 18:15                       ` Štěpán Němec
@ 2010-07-02 20:30                         ` Juanma Barranquero
  2010-07-05  9:49                           ` Seweryn Kokot
  0 siblings, 1 reply; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-02 20:30 UTC (permalink / raw)
  To: Štěpán Němec; +Cc: Seweryn Kokot, help-gnu-emacs

On Fri, Jul 2, 2010 at 20:15, Štěpán Němec <stepan.nemec@gmail.com> wrote:

> I see nothing in the docstrings that would suggest that (unless you use
> `narrow-to-region', obviously -- which the original function discussed
> in this thread did *not* use, although it would have been the right
> thing to do IIRC).

Yes, of course you're right. I was talking about using narrow-to-region.

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-02 20:30                         ` Juanma Barranquero
@ 2010-07-05  9:49                           ` Seweryn Kokot
  2010-07-05 11:46                             ` Juanma Barranquero
       [not found]                             ` <mailman.4.1278330410.9916.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-05  9:49 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu <at> gmail.com> writes:

> > I see nothing in the docstrings that would suggest that (unless you use
> > `narrow-to-region', obviously -- which the original function discussed
> > in this thread did *not* use, although it would have been the right
> > thing to do IIRC).
> 
> Yes, of course you're right. I was talking about using narrow-to-region.

During the weekend I rethought the function I wrote with your help, now I have 
two versions - one without narrow-to-region and markers and the other with 
narrow-to-region functions and without markers. Can we say that the second 
version is more elispy (more elegant and safer) than the first one? 

;; first version
(defun my-multiply-numbers-in-region-or-buffer (&optional multiplier float-
points)
  (interactive
   (list 
	(read-number "Specify a multiplier: " 0.001) 
	(read-number "Specify the number of significant figures: " 3)))
  (let (beg end object end-mark)
	(if (use-region-p)
        (progn
          (setq object "region")
          (setq beg (region-beginning))
          (setq end (region-end)))
      (setq object "buffer")
      (setq beg (point-min))
      (setq end (point-max)))
	(setq end-mark (copy-marker end))
	(goto-char beg)
	(while (re-search-forward "\\([0-9.]+\\)" end-mark t)
	  (replace-match (format (concat "%." (number-to-string float-
points) "f" )  (* (string-to-number (match-string 1)) multiplier))))
	(message "Numbers in %s modified by multiplier %s." object 
multiplier)))

;; second version
(defun my-multiply-numbers-in-region-or-buffer (&optional multiplier float-
points)
  (interactive
   (list
	(read-number "Specify a multiplier: " 0.001)
	(read-number "Specify the number of significant figures: " 3)))
  (let (beg end object end-mark)
	(if (use-region-p)
        (progn
          (setq object "region")
          (setq beg (region-beginning))
          (setq end (region-end)))
      (setq object "buffer")
      (setq beg (point-min))
      (setq end (point-max)))
	(save-restriction
	  (narrow-to-region beg end)
;	  (setq end-mark (point-max-marker))
	  (goto-char (point-min))
;	  (while (re-search-forward "\\([0-9.]+\\)" end-mark t)
	  (while (re-search-forward "\\([0-9.]+\\)" nil t)
	  (replace-match (format (concat "%." (number-to-string float-
points) "f" )  (* (string-to-number (match-string 1)) multiplier))))
	(message "Numbers in %s modified by multiplier %s." object 
multiplier))))







^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-05  9:49                           ` Seweryn Kokot
@ 2010-07-05 11:46                             ` Juanma Barranquero
  2010-07-05 13:40                               ` Seweryn Kokot
       [not found]                             ` <mailman.4.1278330410.9916.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 28+ messages in thread
From: Juanma Barranquero @ 2010-07-05 11:46 UTC (permalink / raw)
  To: Seweryn Kokot; +Cc: help-gnu-emacs

On Mon, Jul 5, 2010 at 11:49, Seweryn Kokot <sewkokot@gmail.com> wrote:

> Can we say that the second
> version is more elispy (more elegant and safer) than the first one?

That is hard to say; different tastes, etc.

I personally would write it like this:

(defun my-multiply-numbers-in-region-or-buffer (&optional multiplier
float-points)
  (interactive
   (list
    (read-number "Specify a multiplier: " 0.001)
    (read-number "Specify the number of significant figures: " 3)))
  (let ((region (use-region-p)))
    (save-restriction
      (widen)
      (narrow-to-region (if region (region-beginning) (point-min))
                        (if region (region-end) (point-max)))
      (goto-char (point-min))
      (while (re-search-forward "\\([0-9.]+\\)" nil t)
        (replace-match (format (concat "%." (number-to-string
float-points) "f" )
                               (* (string-to-number (match-string 1))
multiplier))))
      (message "Numbers in %s modified by multiplier %s."
               (if region "region" "buffer")
               multiplier))))

but that does *not* mean that it is more elegant or lispy; just more
to my tastes :-)

>        (save-restriction

you should use here
          (widen)

>          (narrow-to-region beg end)

    Juanma



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
       [not found]                             ` <mailman.4.1278330410.9916.help-gnu-emacs@gnu.org>
@ 2010-07-05 13:30                               ` David Kastrup
  0 siblings, 0 replies; 28+ messages in thread
From: David Kastrup @ 2010-07-05 13:30 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu@gmail.com> writes:

>>        (save-restriction
>
> you should use here
>           (widen)

Huh?  Why?  I'd rather expect to want an out-of-range if the specified
region is not within the active part of the file.

-- 
David Kastrup


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: How modify numbers in a region by a multiplier?
  2010-07-05 11:46                             ` Juanma Barranquero
@ 2010-07-05 13:40                               ` Seweryn Kokot
  0 siblings, 0 replies; 28+ messages in thread
From: Seweryn Kokot @ 2010-07-05 13:40 UTC (permalink / raw)
  To: help-gnu-emacs

Juanma Barranquero <lekktu <at> gmail.com> writes:

> > Can we say that the second
> > version is more elispy (more elegant and safer) than the first one?
> 
> That is hard to say; different tastes, etc.
> 
> I personally would write it like this:
...
> 
> but that does *not* mean that it is more elegant or lispy; just more
> to my tastes 

Thank you Juanma for your opinion. Nice to have another version of the 
function :-)




^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2010-07-05 13:40 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.0.1277992530.1006.help-gnu-emacs@gnu.org>
2010-07-01 14:19 ` How modify numbers in a region by a multiplier? Marc Mientki
2010-07-01 15:55 ` Andreas Politz
2010-07-01 16:45   ` Pascal J. Bourguignon
2010-07-01 13:55 Seweryn Kokot
2010-07-01 14:16 ` Juanma Barranquero
2010-07-01 14:31   ` Seweryn Kokot
2010-07-01 15:56     ` Juanma Barranquero
2010-07-01 20:10       ` Seweryn Kokot
2010-07-01 20:16         ` Juanma Barranquero
2010-07-01 20:36           ` Seweryn Kokot
2010-07-01 22:38             ` Juanma Barranquero
2010-07-02  6:41               ` Seweryn Kokot
2010-07-02  9:33                 ` Juanma Barranquero
2010-07-02  9:53                   ` Seweryn Kokot
2010-07-02 10:05                     ` Juanma Barranquero
2010-07-02 18:15                       ` Štěpán Němec
2010-07-02 20:30                         ` Juanma Barranquero
2010-07-05  9:49                           ` Seweryn Kokot
2010-07-05 11:46                             ` Juanma Barranquero
2010-07-05 13:40                               ` Seweryn Kokot
     [not found]                             ` <mailman.4.1278330410.9916.help-gnu-emacs@gnu.org>
2010-07-05 13:30                               ` David Kastrup
     [not found]           ` <mailman.2.1278016589.8594.help-gnu-emacs@gnu.org>
2010-07-01 20:42             ` David Kastrup
2010-07-01 21:03             ` Andreas Politz
2010-07-01 15:01   ` Dan Davison
2010-07-01 20:16     ` Seweryn Kokot
     [not found] ` <mailman.0.1277993821.20412.help-gnu-emacs@gnu.org>
2010-07-01 14:19   ` David Kastrup
2010-07-01 16:54 ` Qiang Guo
     [not found] ` <mailman.1.1278003297.20718.help-gnu-emacs@gnu.org>
2010-07-01 18:54   ` Pascal J. Bourguignon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).