using characterCase attribute
using characterCase attribute
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
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
- martin
- Official Nisus Person
- Posts: 5230
- Joined: 2002-07-11 17:14:10
- Location: San Diego, CA
- Contact:
Re: using characterCase attribute
Hello Brad, welcome to using Nisus Writer and its macros!
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.
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.
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.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?
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.
Re: using characterCase attribute
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.
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.
Re: using characterCase attribute
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 710 times
philip
Re: using characterCase attribute
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??
Brad
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
Re: using characterCase attribute
Hello again Brad,
But here is an alternative. Note that the first line in my code is
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:
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:
You can use this code instead of the current last line of my macro "prompt..."
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
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
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
- Attachments
-
ToggleCase.nwm
- Final modified macro
- (7.34 KiB) Downloaded 684 times
philip
Re: using characterCase attribute
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
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 isThis 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
$sel = TextSelection.active
For this code to work, make sure it is placed immediately after the statement creating the $sel variable.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
Now to problem 2. Again using the $sel variable, we can modify the current selection as follows:You can use this code instead of the current last line of my macro "prompt..."Code: Select all
$toggledText = $toggled.join('') $sel.text.replaceInRange $sel.range, $toggledText
Re: using characterCase attribute
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
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
macOS Ventura
Nisus Writer user since 1996
Re: using characterCase attribute
G'day, Philip et al
Excellent! Thanks for that, Philip.
Cheers,
Adrian
Excellent! Thanks for that, Philip.
Cheers,
Adrian
MacBook Pro (M1 Pro, 2021)
macOS Ventura
Nisus Writer user since 1996
macOS Ventura
Nisus Writer user since 1996