Delete and backspace key

Get help using and writing Nisus Writer Pro macros.
Post Reply
lellius
Posts: 54
Joined: 2002-08-15 22:06:44

Delete and backspace key

Post by lellius »

How can i type as a macro command the backspace and the delete key, so that the macro can delete one or multiple character left and right of a specific text character?
Same i like to know how to type left and right arrow so that my macro move the I-beam (skip) one or multiple space character leftwards or rightwards.
I hope i have been clear
Thanks.
giovanni bonaldi
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Delete and backspace key

Post by Kino »

You don't need writing macros for that kind of operations which are already supported in all decent Cocoa applications.

• control-b ←
• control-f →
• control-p ↑
• control-n ↓
• control-d deleteForward
• control-h deleteBackward
• control-option-b moveWordBackward
• control-option-f moveWordForward
• control-k deleteToEndOfParagraph (and put the deleted text in the kill buffer)
• control-y yank (insert from the kill buffer)

and a lot more.

You can assigned those functions to other key combinations by creating a definition file. For that, the easiest way would be to use KeyBindingsEditor (free).
http://www.cocoabits.com/KeyBindingsEditor/

If you want, you could write macros simulating some of those operations. But then, surely you will be irritated at NW Pro's delay in sensing shortcut keys. Not a long delay and no problem in executing menu commands or other kinds of macros but unacceptable when doing this kind of operations. I say so because I tried. I'd like to have Autoindent as a built-in function of NW Pro...
lellius
Posts: 54
Joined: 2002-08-15 22:06:44

Re: Delete and backspace key

Post by lellius »

Kino,
thanks for your long answer.
But probably i haven’t been clear.
I remember that in Nisus Classic it was possible - with a macro - to move the pointer over given text or to cut a character left or right of a I-beam position.
If I well remember, the macro command was

key → (for move rightwards one space)

but i am not sure the image “→” for right-arrow was exactly this (i found the image ⇧ for CAPS, but none either).
Same was possible - with a macro command - to cut one or multiple characters left or right of a I-beam position.
This is precisely what I am searching.
So I imagine a macro over a given text, made like this
---
Cut
key deleteForward
key deleteBackward
Paste
----
where ‘key deleteForward’ and ‘key deleteBackward’ should delete appropriately according to my task.

I hope to be clearer with two examples:

Suppose the given text
“Roman History”
and I want as final result
[i]Roman History[/i] (in italic).
I imagine to do it, running two macro over selected ‘Roman History’ to make it first italic and then deleting the curly quotation marks aside it.

Suppose I have this longer given text (or even a longer one which makes annoying to move manually)
“The more corrupt the state is, the more numerous are the laws” (Tacitus, Annales).
and I want as final result
«The more corrupt the state is, the more numerous are the laws» (Tacitus, Annales).
Again I imagine to run two macros over it:
1. the first one - I already use - to set these «» quotations, aside the text only ‘The more corrupt the state is, the more numerous are the laws’.
2. As, after this macro,- the text '«The more corrupt the state is, the more numerous are the laws»' remains selected, I imagine to run over it a similar macro as above to cut aside the two curly quotation marks.
My question then:
are these macro commands (to delete character or move the pointer) available?
Thanks again for your help
gb
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Delete and backspace key

Post by Kino »

Sorry for misunderstanding your problem, that I rushed to take for my favourite one ;-)

Unfortunately a command corresponding to NW Classic’s “Key” command is not available yet. Once I sent a feature request for a macro command such as “Do Cocoa Action 'deleteForward:'” as a replacement for “Key” command but it does not seem to be high in priority in the list of requested features.

That said. As far as the two particular examples you gave are concerned, it is not difficult to write macros which work in a similar way.

1. Am I right in assuming that what you want to do is (i) Select the text between and (excluding and ) before or after the insertion point, Apply Italic style on it and (ii) delete and ? And you need to do those operations not all at once but seperately for some reason, for example, in order to verify the result of the first step before doing the second?

For the step (i), you can use:

Code: Select all

Find '(?<=“).+?(?=”)', 'E'  # Find/select “...” after the insertion point
Menu ':Format:Italic'
or

Code: Select all

Find '(?<=“).+?(?=”)', 'Er'  # Find/select “...” before the insertion point
Menu ':Format:Italic'
Then, you can run the following macro to do the step (ii).

Code: Select all

$sel = TextSelection.active
if ! $sel.length  # i.e. if there is no visible selection...
	exit  # exit silently
end
$charAfter = Range.new $sel.bound, 1
$sel.text.deleteInRange $charAfter  # delete a character just after the selection
$charBefore = Range.new $sel.location - 1, 1
$sel.text.deleteInRange $charBefore  # delete a character just before the selection
2. Similarly, for the first step, you can use:

Code: Select all

Find and Replace '(?<=“).+?(?=”)', '«\0»', 'E'  # Enclose “...” after the insertion point between « and »
or

Code: Select all

Find and Replace '(?<=“).+?(?=”)', '«\0»', 'Er'  # Enclose “...” before the insertion point between « and »
For the second step, the same macro as that for 1 (ii) will do the job.

If text between and has multiple styles, e.g. Normal (Regular) and Italic, and you want to preserve them, you have to use:

Code: Select all

Find and Replace '(?<=“).+?(?=”)', '«\0»', 'EU'  # Enclose “...” after the insertion point between « and »
or

Code: Select all

Find and Replace '(?<=“).+?(?=”)', '«\0»', 'EUr'  # Enclose “...” before the insertion point between « and »
instead and apply “:Format:Remove Attributes and Styles” on the whole “Find and Replace ...” commands.

And if text between and does or may contain return(s), you have to use “\p{Any}” instead of “.” (AnyCharacter) in all “Find” and “Find and Replace” commands above.
lellius
Posts: 54
Joined: 2002-08-15 22:06:44

Re: Delete and backspace key

Post by lellius »

Kino,
It does work very well
you are great, thank you very much.
I also tested with success the variant
$charAfter = Range.new $sel.bound, 2
$sel.text.deleteInRange $charAfter 
to delete 2 (two) characters and more after selected text.
I didn’t notice any NWP delay in executing the macro.

Well, through the command above I can delete one or more characters.
Is there any similar command to MOVE the cursor one or more characters rightwards or leftwards of a given insertion point, or even to move to beginning or end of a paragraph?
Thanks again if you can answer to me, but it doesn’t hurry.
gb
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Delete and backspace key

Post by Kino »

Is there any similar command to MOVE the cursor one or more characters rightwards or leftwards of a given insertion point, or even to move to beginning or end of a paragraph?
If your document does not have a footnote, the followings are sufficient.

Code: Select all

Find '(?=\G\p{Any}{1})', 'Er'  # move 1 character leftwards
Find '(?<=\G\p{Any}{2})', 'E'  # move 2 characters rightwards
Find '^', 'Er'  # move to paragraph start
Find '$', 'E'  # move to paragraph end
However, if your document contains footnotes, you will notice that the cursor will dive into the note field. If you don’t like it, you need something complicated.

Code: Select all

# move one character rightwards
$sel = TextSelection.active
if $sel.bound < $sel.text.length  # if you have not reached the end of the text object...
	$posRight = Range.new $sel.bound + 1, 0
	TextSelection.setActiveRange $posRight
end

Code: Select all

# move one character lefttwards
$sel = TextSelection.active
if $sel.location > 0  # if you are not in the very beginning of the text object...
	$posLeft = Range.new $sel.location - 1, 0
	TextSelection.setActiveRange $posLeft
end

Code: Select all

# move to paragraph start
if Select Next Paragraph  # if this command successes...
	Select Previous Paragraph
elsif Select Previous Paragraph  # if the previous command failed but this one successes...
	Select Next Paragraph
else  # then, this document must consist of just a single paragraph
	Select Paragraph 1
end
# the paragraph in which the cursor is situated is selected now
Select Start

Code: Select all

# move to paragraph end
if Select Next Paragraph
	Select Previous Paragraph
elsif Select Previous Paragraph
	Select Next Paragraph
else
	Select Paragraph 1
end
# the paragraph in which the cursor is situated is selected now
$sel = TextSelection.active
# Check the last character of the selection
$charValue = $sel.text.characterAtIndex $sel.bound - 1
if $charValue != 10  # if it is not a Return...
	if $charValue != 12  # if it is not a Paragraph/Section Break...
		# then, this must be the last paragraph not having the ending Return/Break
		Select End
		exit 
	end
end
# if the selection ends with a Return/Break, move the cursor just before it.
$beforeEOL = Range.new $sel.bound - 1, 0
TextSelection.setActiveRange $beforeEOL
But what do you really want to do? If that is to move the cursor using your favourite shortcut key, the easiest and the orthodox way is to use Cocoa keybindings as I explained in my first reply. If the movement of the cursor (i.e. modification of the selection) is just a step toward something else, most likely there are simpler and more efficient solutions.
lellius
Posts: 54
Joined: 2002-08-15 22:06:44

Re: Delete and backspace key

Post by lellius »

Hi Kino,
as i said, it was not urgent, so i will test your written macros' functionality with calm, although i am sure they will work.
You are right about the more ortodox way to move the pointer (even to paragraph's beginning or end), and i do it normally, but if i need the command inside a macro, it saves me time.
An other way i will ask you about the functioning of the “clean-up macro” supplied by the application NWP 1.2 itself , which doesn't work properly in my files. Particularly it doesn't execute all requested subtitutions (don't doubt i use 'aE' pref., inside a selected text).
An other funny point is this: i use an Italian Pro keyboard with OSX 10.5.6, but i can't understand why in some applications (FileMaker, TextEdit, end even here inside this window) pressing CAPS +2, i don't get “ or ” (which i want), but subsequently {[{[{.
Isn't curious?
Thanks for everything
gb
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Delete and backspace key

Post by Kino »

Hello again ;-)

To make “Cleanup Punctuation” macro work in selection(s) only, you have to set the find options to ‘asSE’ (a: find/replace all; s: in selection; S: preserve selection; E: PowerFind Pro mode) instead of the original ‘aE’.

And perhaps \s* in the third and the fourth Find and Replace commands would produce unexpected results for \s matches not only ordinary space, tab and no-break space but also Page/Section breaks. So, if there is a paragraph beginning with a punctuation mark, the macro removes all preceding empty paragraphs. In a modified version below, I changed \s* to [\s&&[^\f]]* so that return and break will not be removed. But I’m not sure what to do with \x{2028} (soft return).

The last command of the original macro inserts a space at the end of the document if the last paragraph does not end with return or break. And it transforms, for example, ‘i.e.’ into ‘i.<space>e.’. Not desirable for those who use abbreviations of a similar format. To prevent them from occurring, I added \z (end of document) and \p{Latin}\. to the find expression.

Also I replaced ‘ ’ (space) with \x20 but that is just because ordinary space is replaced with no-break space at times in messages posted to this forum.

Code: Select all

#Changed the macro so that, when there is a visible selection, it works in selection only and preserves selection while executing these Find and Replace commands. If there is no visible selection but just a caret (insertion point), the macro works on the whole document, exactly in the same way as the original macro.

#ATTENTION: For a selection containing a footnote reference, the note text associated with it will be processed too, even if the latter does not look selected. ~kino

$opt = ‘aE’
$sel = TextSelection.active
if $sel.length
	$opt = ‘asSE’
end

Find and Replace ‘\x20+’, ‘\x20’, $opt  #Replace multiple spaces with one,
Find and Replace ‘([,;:!?])\1+’, ‘\1’, $opt  #Remove duplicate consecutive punctuation
Find and Replace ‘^[\s&&[^\f]]*[,.;:!?]+’, ‘’, $opt  #Remove punctuation and precdeing whitespace (except return and break) from start of paragraph with preceding whitespace if any.
Find and Replace ‘[\s&&[^\f]]+(?=[,.;:!?])’, ‘’, $opt  #Remove whitespace (except return and break) ahead of punctuation.
Find and Replace ‘^[\t\x20]+|[\t\x20]+$’, ‘’, $opt  #Remove leading and trailing tab or space
Find and Replace ‘,(?=[.;:!?])’, ‘’, $opt  #Remove the comma preceding any punctuation mark.

#Add a space following any punctuation mark not followed by punctuation, whitespace, or digit
Find and Replace ‘(?<=[;!?])(?![,.;:!?\'\’"”\s]|\z)|(?<=[,.:])(?![,.;:!?\'\’"”\s\d]|\p{Latin}\.|\z)’, ‘\x20’, $opt
I modified the original macro where I noticed something unexpected to me but it is impossible to write a this kind of macro which satisfies everyone. Nothing wrong with the original “Cleanup Punctuation” macro as it is.

Whether you use the original macro or my version, you are likely to be forced to modify some Find and Replace commands or comment them out to disable them in order to make the macro fit your writing habit and the punctuation rules of your language. Unfortunately I don’t know Dante’s language but, for French text, the fourth Find and Replace command (Remove white-space ahead of punctuation) is indésirable definitively.

And I may have introduced bugs while modifying the original macro. Sorry in advance for them.

As to the smart quotes problem, I cannot reroduce it in TextEdit with my ANSI (US) physical keyboard using Italian Pro keyboard layout (OS X 10.5.6). But it looks suggestive that US keyboard layout assigns opening double quote to “option-[” and closing double quote to “option-shift-[”, i.e. “option-{”. So I tend to think it has something to do with the Italian physical keyboard. Perhaps OS X (or your Mac?), does it fails to recognize the type of your physical keyboard correctly?
lellius
Posts: 54
Joined: 2002-08-15 22:06:44

Re: Delete and backspace key

Post by lellius »

Hi Kino
again thank you very much.

Your macros do work pretty well (even if I needed some time to realise that “r” - as macro option - means search backwards).

Regarding removing white-space ahead of punctuation in he fourth line, I followed your suggestion, it is better so.

Regarding the smart quotes, the problem is not the Italian keyboard description (there are in Mac OSX 10.5.6 two of them “Italian” and “Italian Pro”, for reasons which would take time to explain.
As soon you know which key-combination (in which keyboard description) gives you the intended result, you just press it.
So in Italian Pro, to type " (simple quotes), you have to press the key combination Shift_2 (with 2, as third key of fifth row from left, same as USA keyboard).
The problem is that the said key combination DOES WORK inside Nisus Writer Pro (where you can get also smart quotes “”, having selected them in Pref.), similarly it does also in other applications, but NOT for instance in Textedit, in Filemaker Pro, and even now typing here inside this window, where - instead of the expected “” - I get the funny result {[{[{ (subsequently and anternatively).

As last point, I would like now to submit you a macro, I built to give typographic elegance to texts taken from internet, where vowels (upper and lower case) are usually accented like that: E' e', E’ e’, E` e`, E´e´, which however should be typed È è according to Italian rules.
I intend to execute the macro always on a selected text, and obviously preserving attributes (upper or lower case, italic or bold, etc.)
But my macro doesn’t work properly and doesn’t esecute all occurrences in an unique command: sometimes it does work, sometimes it replaces only some vowels, sometimes I have to repeat execution on the selected text, and so on.
Can you tell me please what is wrong? options?

Find and Replace '(A)(\'\’|`|´)', 'À', 'Esa-i'
Find and Replace '(E)(\'|\’|`|´)', 'È', 'Esa-i'
Find and Replace '(I)(\'|\’|`|´)', 'Ì', 'Esa-i'
Find and Replace '(O)(\'|\’|`|´)', 'Ò', 'Esa-i'
Find and Replace '(U)(\'|\’|`|´)', 'Ù', 'Esa-i'
Find and Replace '(a)(\'|\’|`|´)', 'à', 'Esa-i'
Find and Replace '(e)(\'|\’|`|´)', 'è', 'Esa-i'
Find and Replace '(i)(\'|\’|`|´)', 'Esa-i'
Find and Replace '(o)(\'|\’|`|´)', 'ò', 'Esa-i'
Find and Replace '(u)(\'|\’|`|´)', 'ù', 'Esa-i'
Find and Replace '(à|À|è|é|È|ì|Ì|ò|ó|Ò|ù|Ù)(\'|\’)', '\1' , 'Esa-i' #Final command to delete any remained ' ’`´

Thanks in advance.
gb
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Delete and backspace key

Post by Kino »

The problem is that the said key combination DOES WORK inside Nisus Writer Pro (where you can get also smart quotes “”, having selected them in Pref.), similarly it does also in other applications, but NOT for instance in Textedit, in Filemaker Pro, and even now typing here inside this window, where - instead of the expected “” - I get the funny result {[{[{ (subsequently and anternatively).
[1] For smart quotes conversion, Nisus Writer Pro uses its own function. So it is natural that you get different results from other applications whose smart quotes feature seems to be buggy.

[2] I don't have Filemaker Pro and Safari 3.2.1 I'm running does not have the smart quotes feature. So I cannot tell about them. However, in TextEdit, when I hit shift-2, Italian Pro keyboard layout gives me correct results: " (smart quotes disabled) and “ or ” (smart quotes enabled).

[3] What makes the difference between us would be the physical keyboard. My Mac is connected to a US (ANSI) physical keyboard and yours would have an European (ISO) physical keyboard (or am I wrong?). So presumably the bug has something to do with the recognition of the physical keyboard type connected to your Mac.

But perhaps "Change Keyboard Type" (in the Keyboard tab of the Keyborad & Mouse System Preferences pane) would solve the problem. Try it if you have not.
But my macro doesn’t work properly and doesn’t esecute all occurrences in an unique command: sometimes it does work, sometimes it replaces only some vowels, sometimes I have to repeat execution on the selected text, and so on.
[1] If you do a Find and Replace, you will notice that the newly inserted text is selected. So if the first command successed, the selection is not the original selection any more but "À". That causes your macro to misbehave. When applying multiple Find and Replace commands on the same selection, you have to use not only s option (in selection) but also S option (keep selection). An appropriate set of find options would be 'EsSa-i'.

[2] There seems to be typos in your macro:

Code: Select all

 Find and Replace '(A)(\'\’|`|´)', 'À', 'Esa-i'
Find and Replace '(i)(\'|\’|`|´)', 'Esa-i'
should be

Code: Select all

 Find and Replace '(A)(\'|\’|`|´)', 'À', 'EsSa-i'
Find and Replace '(i)(\'|\’|`|´)', 'ì', 'EsSa-i'
So your macro will become...

Code: Select all

Find and Replace '(A)(\'|\’|`|´)', 'À', 'EsSa-i'
Find and Replace '(E)(\'|\’|`|´)', 'È', 'EsSa-i'
Find and Replace '(I)(\'|\’|`|´)', 'Ì', 'EsSa-i'
Find and Replace '(O)(\'|\’|`|´)', 'Ò', 'EsSa-i'
Find and Replace '(U)(\'|\’|`|´)', 'Ù', 'EsSa-i'
Find and Replace '(a)(\'|\’|`|´)', 'à', 'EsSa-i'
Find and Replace '(e)(\'|\’|`|´)', 'è', 'EsSa-i'
Find and Replace '(i)(\'|\’|`|´)', 'ì', 'EsSa-i'
Find and Replace '(o)(\'|\’|`|´)', 'ò', 'EsSa-i'
Find and Replace '(u)(\'|\’|`|´)', 'ù', 'EsSa-i'
Find and Replace '(à|À|è|é|È|ì|Ì|ò|ó|Ò|ù|Ù)(\'|\’)', '\1' , 'EsSa-i'
That works but if you want to make your code more economical...

[1] You can use (?:   ) instead of (   ) to gather elements in a group when there is not a back reference (such as \1, \2 ...) corresponding to it. (?:   ) is said to use less memory but the difference should be unnoticeably small.

[2] However, in this macro, all elements in (   ) are single characters. So you can get rid of | (OR operator) if you use [   ] instead of (   ) or (?:   ).

[3] Instead of the last command, you can put + (one or more times) just after [\'\’`´] of the preceding commands to remove those characters including repetitive ones.

Then, the macro will be something like this:

Code: Select all

Find and Replace 'A[\'\’`´]+', 'À', 'EsSa-i'
Find and Replace 'E[\'\’`´]+', 'È', 'EsSa-i'
Find and Replace 'I[\'\’`´]+', 'Ì', 'EsSa-i'
Find and Replace 'O[\'\’`´]+', 'Ò', 'EsSa-i'
Find and Replace 'U[\'\’`´]+', 'Ù', 'EsSa-i'
Find and Replace 'a[\'\’`´]+', 'à', 'EsSa-i'
Find and Replace 'e[\'\’`´]+', 'è', 'EsSa-i'
Find and Replace 'i[\'\’`´]+', 'ì', 'EsSa-i'
Find and Replace 'o[\'\’`´]+', 'ò', 'EsSa-i'
Find and Replace 'u[\'\’`´]+', 'ù', 'EsSa-i'
However, there is no need to write your macro in this way. If you find the original form more confortable, you don't need changing it.

Edit: I added two lines as I noticed another typo.
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Delete and backspace key

Post by phspaelti »

…and finally if you use the combining diacritic (U+0300) instead you can actually write the whole thing like this:

Code: Select all

Find and Replace '(?<=[aeiou])[\’\'´`]+', '̀', 'EsSa'
(for what it's worth…)
philip
lellius
Posts: 54
Joined: 2002-08-15 22:06:44

Re: Delete and backspace key

Post by lellius »

Thank to everybody.
Soon i will come back with other question.
gb
Kino
Posts: 400
Joined: 2008-05-17 04:02:32

Re: Delete and backspace key

Post by Kino »

Nisus Writer Pro 1.3 comes with numerous macro enhancements. Related to this thread, the most interesting is Send Selector command which can be used as a replacement of NW Classic's Key command in most cases.
lellius wrote:So I imagine a macro over a given text, made like this
---
Cut
key deleteForward
key deleteBackward
Paste
----
where ‘key deleteForward’ and ‘key deleteBackward’ should delete appropriately according to my task.

Code: Select all

Cut
Send Selector 'deleteForward:'
Send Selector 'deleteBackward:'
Paste
And...
Is there any similar command to MOVE the cursor one or more characters rightwards or leftwards of a given insertion point, or even to move to beginning or end of a paragraph?

Code: Select all

Send Selector 'moveRight:' # or 'moveForward:'
Send Selector 'moveLeft:' # or 'moveBackward:'
Send Selector 'moveToBeginningOfParagraph:'
Send Selector 'moveToEndOfParagraph:'
In addition to the web page mentionned in Nisus Macro Reference, you can look at Apple's reference.

Also Send Selector 'insertTab:' works like (hitting) the tab key when navigating, for example, in the Print dialog. The macro below uses Send Selector 'insertTab:' to move from an input field to another and uses Send Text command to put page numbers.

Code: Select all

 ### Print Selected Pages ###

Require Pro Version 1.3

$sel = TextSelection.active
if $sel == undefined
	exit  # no document is active
end

$kbdUIMode = undefined
begin Perl
	$kbdUIMode = `defaults read -g 'AppleKeyboardUIMode' 2>/dev/null`;
	chomp $kbdUIMode;
end
if $kbdUIMode > 1
	exit 'This macro does not work properly when Full keyboard access is set to "All controls", exit...'
end

$firstPage = $sel.text.pageNumberAtIndex $sel.location, false
$lastPage =  $sel.text.pageNumberAtIndex $sel.bound - 1, false
Send Selector 'printDocument:'
Send Selector 'insertTab:'
Send Text $firstPage
Send Selector 'insertTab:'
Send Text $lastPage

# Press Default Button
The last command (Press Default Button) is commented out because I'm using this macro not to print selected pages but to export them as PDF and I have to do the last step manually.

The macro checks if the Full keyboard access option in Keyboard Shortcuts tab of Keyboard & Mouse System pref pane is set to "Text boxes and lists only" because it will not work properly with "All Controls". And there seems to be no workaround. Unfortunately, insertTab: does not work exactly in the same way as the tab key. This is an Apple bug.
Post Reply