contract 5.6.7.8 to 5-8

Get help using and writing Nisus Writer Pro macros.
Post Reply
dakofi
Posts: 17
Joined: 2003-02-07 07:48:35

contract 5.6.7.8 to 5-8

Post by dakofi »

Hi

I’d like to contract 5.6.7.10.11.12.20 to an expression like 5-7.10-12.20. The separators are dots (or commas if better). Non continuous numbers are separated by dots and these expressions must not be shortened. As well no contraction if the higher value is the following number of the lower value e.g. 5.6 or 5.6.9.11

Thanks for your feedback.

dakofi
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: contract 5.6.7.8 to 5-8

Post by Kino »

The following macro will do the job. It also sorts numbers. I.e. 20.5.11.6.7.10.12 will be 5-7.10-12.20.

Code: Select all

### Bind Numbers ###

# Convert selected text(s) such as
#   125, 44, 12, 35, 521, 9, 41, 124, 334, 42, 78, 5, 123, 335, 23, 1, 15, 31, 81, 4, 14, 43, 333, 3
# into
#   1, 3-5, 9, 12, 14-15, 23, 31, 35, 41-44, 78, 81, 123-125, 333-335, 521

# If there is no selection, the whole document will be processed.

# You can customize separator (', ' in the example above) and joiner ('-' in the example above)
# by modifying the definition of $separator = $sep and $joiner near the beginning of the macro.

Require Application Version '3.1'
Debug.setDestination 'none'
$doc = Document.active
$separator = $sep = '.'
$joiner = '-'

$sel = TextSelection.active
if ! $sel.length
   Select All Document
end

$spChars = Hash.new '$', '\$', '(', '\(', ')', '\)', '*', '\*', '+', '\+', '.', '\.', '?', '\?', '\\', '\x5C', '^', '\^', '{', '\{', '|', '\|', '}', '\}', '[', '\[', ']', '\]'
$range = Range.new 0, $sep.length
$sep.transliterateInRange $range, $spChars

$findExp = '[0-9]+(?:' & $sep
$findExp &= '[0-9]+)+'
$numFound = Find All $findExp, 'Es'
if ! $numFound
   Exit 'Nothing found, exit...'
end

$selections = $doc.textSelections
foreach $sel in reversed $selections
   $numbers = $sel.subtext
   $numbers = $numbers.split $separator
   $numbers.sort 'n'
   $converted = Array.new
   $continuous = false
   $start = $last = $numbers.firstValue
   foreach $num in $numbers
      $diff = $num - $last
      if $diff > 1
         if $continuous == true
            $converted.appendValue "$start$joiner$last"
            $continuous = false
         else
            $converted.appendValue $start
         end
         $start = $num
      elsif $diff == 1
         $continuous = true
      end
      $last = $num
   end
   if $continuous == true
      $converted.appendValue "$start$joiner$last"
   else
      $converted.appendValue $last
   end
   $converted = $converted.join $separator
   $converted = Cast to String $converted
   Debug.log "$numbers\n => $converted"
   $sel.text.replaceInRange $sel.range, $converted
end

### end of macro ###
formatted macro file:
http://www2.odn.ne.jp/alt-quinon/files/ ... rs_nwm.zip
(with this file, you have modify the definition of $separtor from ', ' to '.')
dakofi
Posts: 17
Joined: 2003-02-07 07:48:35

Re: contract 5.6.7.8 to 5-8

Post by dakofi »

Hi

The macro preforms very well but it does a tiny little too much.
In case of only two successive values, e.g. 1.2, the macro replaces the separator as well by the joiner.

With your example
# 125, 44, 12, 35, 521, 9, 41, 124, 334, 42, 78, 5, 123, 335, 23, 1, 15, 31, 81, 4, 14, 43, 333, 3
# into
# 1, 3-5, 9, 12,14-15, 23, 31, 35, 41-44, 78, 81, 123-125, 333-335, 521

I'd like to have 14.15 insted of 14-15

Would you fix that, please?

Thanks for your feedback.

dakofi
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: contract 5.6.7.8 to 5-8

Post by Kino »

I added an option for modifying the behaviour of the macro. But as far as I observed, "14-15" is a common format for index page numbers.

Code: Select all

### Bind Numbers ###

# Works on selection(s). If there is no selection, the whole document will be processed.

# This macro converts selected text(s) such as
#   125, 44, 12, 35, 521, 9, 41, 124, 334, 42, 78, 5, 123, 335, 23, 1, 15, 31, 81, 4, 14, 43, 333, 3
# into
#   1, 3-5, 9, 12, 14-15, 23, 31, 35, 41-44, 78, 81, 123-125, 333-335, 521
# or
#   1, 3-5, 9, 12, 14, 15, 23, 31, 35, 41-44, 78, 81, 123-125, 333-335, 521

# If $sepJustTwoNums is set to true, "14" and "15" will be "14, 15".
# If it is set to false, "14" and "15" will be "14-15".

# You can customize separator (', ' in the example above) and joiner ('-' in the example above)
# by modifying the definition of $separator = $sep and $joiner near the beginning of the macro.

$sepJustTwoNums = true
$separator = $sep = '.'
$joiner = '-'

Require Application Version '3.1'
$doc = Document.active

$sel = TextSelection.active
if ! $sel.length
   Select All Document
end

if $sepJustTwoNums == true
   $min = 3
else
   $min = 2
end

$spChars = Hash.new '$', '\$', '(', '\(', ')', '\)', '*', '\*', '+', '\+', '.', '\.', '?', '\?', '\\', '\x5C', '^', '\^', '{', '\{', '|', '\|', '}', '\}', '[', '\[', ']', '\]'
$range = Range.new 0, $sep.length
$sep.transliterateInRange $range, $spChars

$findExp = '[0-9]+(?:' & $sep
$findExp &= '[0-9]+)+'
$numFound = Find All $findExp, 'Es'
if ! $numFound
   Exit 'Nothing found, exit...'
end

$selections = $doc.textSelections
foreach $sel in reversed $selections
   $numbers = $sel.subtext
   $numbers = $numbers.split $separator
   $numbers.sort 'n'
   $converted = Array.new
   $continuous = false
   $baseNum = $last = $numbers.firstValue
   $numGroups = Hash.new
   $numGroups{$baseNum} = Array.new $baseNum
   foreach $n in $numbers
      $diff = $n - $last
      if $diff > 1
         $numGroups{$n} = Array.new $n
         $baseNum = $n
      elsif $diff == 1
         $numGroups{$baseNum}.appendValue $n
      end
      $last = $n
   end
   $baseNumbers = $numGroups.keys
   $baseNumbers.sort 'n'
   foreach $i in $baseNumbers
      $nums = $numGroups{$i}
      if $nums.count >= $min
         $value = $nums.firstValue & $joiner
         $value &= $nums.lastValue
      else
         $value = $nums.join $separator
      end
      $converted.appendValue $value
   end
   $converted = $converted.join $separator
   $converted = Cast to String $converted
   $sel.text.replaceInRange $sel.range, $converted
end

### end of macro ###
formatted macro file with options set differently (you can customize anyway):
http://www2.odn.ne.jp/alt-quinon/files/ ... rs_nwm.zip
dakofi
Posts: 17
Joined: 2003-02-07 07:48:35

Re: contract 5.6.7.8 to 5-8

Post by dakofi »

It's working!
Marvelous!!

I couldn't have solved the problems without you.

You did a great job.

Thanks Kino for your support.

dakofi
Post Reply