using characterCase attribute

Get help using and writing Nisus Writer Pro macros.
Post Reply
B.Otter
Posts: 27
Joined: 2021-02-06 15:24:00

using characterCase attribute

Post by B.Otter »

Greetings,

I am new to Nisus Writer Pro and the macro language. I'd like to write a general purpose "Toggle Case" macro that could be applicable to the Unicode range, changing the uppercase character at the caret to lowercase and vice versa. I have a working version for the ASCII range but wonder if there's a simple solution for the entire range of Unicode?

I've had no luck with the attribute "characterCase" as in, (with a selection of a single character):

$attrs = TextSelection.active.displayTypingAttributes.characterCase

Is there a form of usage or a context in which "characterCase" is ever nonZero?

Thanks,
Brad
User avatar
martin
Official Nisus Person
Posts: 5227
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

Re: using characterCase attribute

Post by martin »

Hello Brad, welcome to using Nisus Writer and its macros!
B.Otter wrote: 2021-02-15 13:18:53 I'd like to write a general purpose "Toggle Case" macro that could be applicable to the Unicode range, changing the uppercase character at the caret to lowercase and vice versa.
Perhaps you're writing this macro as a learning exercise. But if not I just want to point out we have a command for this via the menu Edit > Transform Text > To Toggled Case.
I've had no luck with the attribute "characterCase" as in, (with a selection of a single character):

$attrs = TextSelection.active.displayTypingAttributes.characterCase

Is there a form of usage or a context in which "characterCase" is ever nonZero?
The value of this display attribute (formatting) depends on the state of the menu Format > Letter Case. It does not tell you anything about the underlying text's character codes; it tells you if the user has applied any display transformations. The latter works like other kinds of formatting (eg: bold font) and is enforced dynamically by Nisus Writer's display processing. You might read my blog post on letter case conversions for more details.

What is probably going to be more helpful to you is something like the \p{Upper} or \p{Lower} search patterns that are part of regular expression's Unicode support. Writing Nisus Writer macro code to manually handle all the possible letters in Unicode would be quite a task!

I hope that helps. Please let me know if you have any more questions.
B.Otter
Posts: 27
Joined: 2021-02-06 15:24:00

Re: using characterCase attribute

Post by B.Otter »

Martin, thank you, totally clear and helpful.

I had overlooked the "Edit > Transform Text > To Toggled Case" — a perfect fit for my editing needs. Interestingly, it looks as though the transforms to UPPERCASE and lowercase seem to work with diacriticals such as ō and Ō, however, the "To Toggled Case" leaves each of these characters in their original states.

Agreed, a complete table for unicode case conversions would be onerous.

The usage for the attribute "characterCase" is also clear and consistent—when I take the macro manual as written. Smile.

In any case, all helpful.

Thanks.
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: using characterCase attribute

Post by phspaelti »

Since the "To UPPERCASE" and "to lowercase" work, as you point out, you can leverage them to create a togglecase macro as appended.
Attachments
ToggleCase.nwm
(5.89 KiB) Downloaded 595 times
philip
B.Otter
Posts: 27
Joined: 2021-02-06 15:24:00

Re: using characterCase attribute

Post by B.Otter »

phspaelti wrote: 2021-02-17 09:06:03 Since the "To UPPERCASE" and "to lowercase" work, as you point out, you can leverage them to create a togglecase macro as appended.
Philip, thank you, learned from your code.

Brad
B.Otter
Posts: 27
Joined: 2021-02-06 15:24:00

Re: using characterCase attribute

Post by B.Otter »

Ok, I took Phil's elegant, general solution to toggling, which works with diacriticals and added code at the beginning and at the end so that:

1) if nothing selected, select one character to right of the caret

2) paste the modified text back into the document — used the clipboard.

Wondering, is there a more elegant solution to replace the toggled text than using the clipboard??

Code: Select all

# 1) code added before Phil's ToggleCase

# if no selection, select one character to right of caret
$sel_len = Selection Length
if $sel_len < 1
	$sel_loc = Selection Location 
	Select Start
	$sel_len = 1
	Set Selection $sel_loc, $sel_len
End 

### Phil’e code goes here ending with the ForEach Loop
### not included inline because the code line beginning "foreach" threw a server error on Preview

# 2) update the document with the toggle

# replace selected text in document
# this seems a brute force solution to paste text back
# overwrites then pastes the default clipboard
# I imagine there is a more elegant solution
# but I couldn't find a solution using .insertText

Write Clipboard $toggled.join('')
Edit:Paste:Paste Text Only
Select End
Brad
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: using characterCase attribute

Post by phspaelti »

Hello again Brad,
B.Otter wrote: 2021-02-17 12:00:29 1) if nothing selected, select one character to right of the caret

2) paste the modified text back into the document — used the clipboard.

Wondering, is there a more elegant solution to replace the toggled text than using the clipboard??
First to part 1. Clearly you have found a solution.
But here is an alternative. Note that the first line in my code is

Code: Select all

$sel = TextSelection.active
This creates a selection variable which you can use to check properties of the current selection, and you can also use to modify the selection:

Code: Select all

if sel.length < 1
  if $sel.location < $sel.text.length
    $sel.length = 1
    TextSelection.setActiveRange $sel.range
  else
    die 'Sorry! No space left'
  end
end
For this code to work, make sure it is placed immediately after the statement creating the $sel variable.

Now to problem 2. Again using the $sel variable, we can modify the current selection as follows:

Code: Select all

$toggledText = $toggled.join('')
$sel.text.replaceInRange $sel.range, $toggledText
You can use this code instead of the current last line of my macro "prompt..."
Attachments
ToggleCase.nwm
Final modified macro
(7.34 KiB) Downloaded 570 times
philip
B.Otter
Posts: 27
Joined: 2021-02-06 15:24:00

Re: using characterCase attribute

Post by B.Otter »

Good morning, Phil, and another "Thank you." I'm going to school on your code. Liked your use of .split, .push, and .join. And this time some helpful examples of objects, selection and range. These have helped me to get a feel for the language and where to look. Like the section named "Text Object - Modifying Text" to find .replaceInRange.

Thanks for the jump start,

Brad
phspaelti wrote: 2021-02-17 17:01:20
First to part 1. Clearly you have found a solution.
But here is an alternative. Note that the first line in my code is

Code: Select all

$sel = TextSelection.active
This creates a selection variable which you can use to check properties of the current selection, and you can also use to modify the selection:

Code: Select all

if sel.length < 1
  if $sel.location < $sel.text.length
    $sel.length = 1
    TextSelection.setActiveRange $sel.range
  else
    die 'Sorry! No space left'
  end
end
For this code to work, make sure it is placed immediately after the statement creating the $sel variable.

Now to problem 2. Again using the $sel variable, we can modify the current selection as follows:

Code: Select all

$toggledText = $toggled.join('')
$sel.text.replaceInRange $sel.range, $toggledText
You can use this code instead of the current last line of my macro "prompt..."
adryan
Posts: 561
Joined: 2014-02-08 12:57:03
Location: Australia

Re: using characterCase attribute

Post by adryan »

G'day, Philip et al

Thanks for another useful addition to the Macro collection, Philip.

One tiny little tweak, though, if you could: at present, it only seems to work on the first of a set of non-contiguous selections.

Cheers,
Adrian
MacBook Pro (M1 Pro, 2021)
macOS Ventura
Nisus Writer user since 1996
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: using characterCase attribute

Post by phspaelti »

ToggleCase (multi).nwm
(8.05 KiB) Downloaded 833 times
philip
adryan
Posts: 561
Joined: 2014-02-08 12:57:03
Location: Australia

Re: using characterCase attribute

Post by adryan »

G'day, Philip et al

Excellent! Thanks for that, Philip.

Cheers,
Adrian
MacBook Pro (M1 Pro, 2021)
macOS Ventura
Nisus Writer user since 1996
Post Reply