It's too late but here is a macro which increases or decreases the saturation of all text colours in selection(s) except black.
- If there is no visible selection, the whole document will be processed.
- New saturation is determined in the following manner:
• if user input = 0, it is set to $fixedSaturationValue (you can customize it);
• if user input > 0, it is set to -1/
n * (
x - 1)² + 1 (
n: user input;
x: original saturation);
• if user input < 0, it is set to 1/
n *
x² (
n: user input;
x: original saturation).
In other words, with a positive number, 1, 1.5, 3... given as user input, the macro increases the saturation, with a negative number, -1, -1.5, -3... given as user input, the macro decreases the saturation and if your input is 0, the value of $fixedSaturationValue will be applied unconditionally.

- formulas.png (60.47 KiB) Viewed 4426 times
As I'm not familiar with colours, I don't know if the formulas used to calculate a new saturation are appropriate. I think you can modify the routines for the calculations easily as far as Nisus Writer Macro enables you to do although the current command set of math functions is very poor.
While RGB is easy to create a new colour, HSV (HSB) looks handier for manipulating existent colours. And coding the conversion from RGB to HSV and from HSV to RGB is cumbersome and boresome. Also such calculations are inevitably inaccurate. So I sent a feature request for something like:
$colorObject.hue
$colorObject.saturation
$colorObject.value
$colorObject = Color.newWithHSVA
which will make this kind of macros much simpler.
Code: Select all
### Alter Saturation ###
$fixedSaturationValue = 0.84 # 0 ≤ $fixedSaturationValue ≤ 1
Require Pro Version 1.2
$doc = Document.active
if $doc == undefined
exit
end
if $fixedSaturationValue < 0
$fixedSaturationValue = 0
elsif $fixedSaturationValue > 1
$fixedSaturationValue = 1
end
$sels = $originalSels = $doc.textSelections
if ! $sels.firstValue.length
$sels = Array.new # construct $sels corresponding to Select All Document
foreach $text in $doc.allTexts
if $text.length
$sel = TextSelection.newWithLocationAndBound $text, 0, $text.length
$sels.appendValue $sel
end
end
end
$message = "Input a number (0 for fixed Saturation: $fixedSaturationValue)"
$detail = 'Saturation is set to: -1/n * (x - 1)² + 1 (n > 0); 1/n * x² (n < 0)'
$n = Prompt Input $message, $detail, '', '2'
if $n == 0
$fixedSaturation = true
else
$fixedSaturation = false
$increase = true
$n = Cast to Float $n
if $n < 0
$increase = false
$n = $n * -1
end
end
$black = Color.newWithRGBA 0, 0, 0, 1
$colors = Hash.new
foreach $sel in $sels
$charIndex = $sel.location
$limit = $sel.bound
while $charIndex < $limit
$attr = $sel.text.displayAttributesAtIndex $charIndex
$range = $sel.text.rangeOfDisplayAttributesAtIndex $charIndex
$textColor = $attr.textColor
if $textColor != $black
$colorSel = TextSelection.new $sel.text, $range
if $colors{$textColor} == undefined
$colors{$textColor} = Array.new $colorSel
else
$colors{$textColor}.appendValue $colorSel
end
end
$charIndex = $range.bound
end
end
$textColors = $colors.keys
if ! $textColors.count
exit 'No colored text found, exit...'
end
foreach $textColor in $textColors
$red = $textColor.red
$green = $textColor.green
$blue = $textColor.blue
$alpha = $textColor.opacity
$rgb = Array.new $red, $green, $blue
$rgb.sort
$max = $value = $rgb.lastValue
$min = $rgb.firstValue
$maxMin = $max - $min
if $value == 0 # black
$saturation = $hue = 0
else
$saturation = $maxMin / $max
$value = $max
if $maxMin == 0 # gray scale
$hue = undefined
elsif $max == $red
$hue = $green - $blue
$hue = $hue * 60
$hue = $hue / $maxMin
elsif $max == $green
$hue = $blue - $red
$hue = $hue * 60
$hue = $hue / $maxMin
$hue += 120
elsif $max == $blue
$hue = $red - $green
$hue = $hue * 60
$hue = $hue / $maxMin
$hue += 240
end
if $hue < 0
$hue += 360
elsif $hue > 360
$hue -= 360
end
end
if $fixedSaturation == true
$newSaturation = $fixedSaturationValue
else
if $increase == true
# calculate the new and increased value of saturation
$newSaturation = $saturation - 1
$newSaturation = $newSaturation * $newSaturation
$newSaturation = $newSaturation / $n
$newSaturation = $newSaturation * -1
$newSaturation += 1
else
# calculate the new and decreased value of saturation
$newSaturation = $saturation * $saturation
$newSaturation = $newSaturation / $n
end
end
if $newSaturation == 0 # gray scale
$newColor = Color.newWithRGBA $value, $value, $value, $alpha
$hi = undefined # for debug
else
$hi = Cast to Int $hue / 60, false
$f = $hue / 60
$f -= $hi
$hi = $hi % 6
$p = 1 - $newSaturation
$p = $value * $p
$q = $f * $newSaturation
$q = 1 - $q
$q = $value * $q
$t = 1 - $f
$t = $t * $newSaturation
$t = 1 - $t
$t = $value * $t
if $hi == 0
$newColor = Color.newWithRGBA $value, $t, $p, $alpha
elsif $hi == 1
$newColor = Color.newWithRGBA $q, $value, $p, $alpha
elsif $hi == 2
$newColor = Color.newWithRGBA $p, $value, $t, $alpha
elsif $hi == 3
$newColor = Color.newWithRGBA $p, $q, $value, $alpha
elsif $hi == 4
$newColor = Color.newWithRGBA $t, $p, $value, $alpha
elsif $hi == 5
$newColor = Color.newWithRGBA $value, $p, $q, $alpha
end
end
$colorSels = $colors{$textColor}
$doc.setSelections $colorSels
Document.setActive $doc # Is it necessary?
Set Text Color $newColor
end
$doc.setSelections $originalSels # restore selection
### end of macro ###
Formatted macro file:
http://www2.odn.ne.jp/alt-quinon/files/ ... on_nwm.zip