Find and replace using attributes works, but macro doesn't

Get help using and writing Nisus Writer Pro macros.
Post Reply
davidmacd
Posts: 6
Joined: 2003-06-12 10:14:22
Location: SCOTLAND

Find and replace using attributes works, but macro doesn't

Post by davidmacd »

I have a Powerfind Pro expression which works exactly as it should. It does not work when converted to a macro.

The expression also uses an attribute, namely baseline set to 'No Super/Sub'.

The expression is simple:

-([\d])

That is an en dash before the parenthesis, not a hyphen.

The replacement is also simple:

-\1

The expression is meant to find an en dash followed by any digit, but only in normal (i.e. not superscript) text, and replace it with a hyphen. It works as expected using Find and Replace. However, when converted to a macro, it doesn't, at least not for me. When using the macro, all occurrences get changed, including those in superscript.

The macro code is:

Find and Replace @Text<(–[\d])>, @Text<\1>, 'Eau'

Can anyone confirm that my observation is correct, i.e. that Find and Replace functions as expected, but not the apparently equivalent macro. Or can anyone point out where I have made a mistake?
adryan
Posts: 563
Joined: 2014-02-08 12:57:03
Location: Australia

Re: Find and replace using attributes works, but macro doesn't

Post by adryan »

G'day, davidmacd et al

I see the same thing: F/R works, but not when Macroized.

Cheers,
Adrian
MacBook Pro (M1 Pro, 2021)
macOS Ventura
Nisus Writer user since 1996
davidmacd
Posts: 6
Joined: 2003-06-12 10:14:22
Location: SCOTLAND

Re: Find and replace using attributes works, but macro doesn't

Post by davidmacd »

The macro code I posted above had a typo (missing hyphen in the replacement). It should be:

Find and Replace @Text<–([\d])>, @Text<-\1>, 'Eau'

And is set to use 'No Super/Sub'.

The macro should replace an en dash with a hyphen, but only in normal text, not superscript. It doesn't: it operates on all text, including superscript.
User avatar
phspaelti
Posts: 1313
Joined: 2007-02-07 00:58:12
Location: Japan

Re: Find and replace using attributes works, but macro doesn't

Post by phspaelti »

I can confirm—as has Adrian already—that apparently the "No Subscript" style does not seem to be operative in a macroized statement.
Of course these commands, where the applied style in the macro code is critical, are extremely delicate.
philip
User avatar
martin
Official Nisus Person
Posts: 5228
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

Re: Find and replace using attributes works, but macro doesn't

Post by martin »

This is unfortunately an awkward bit of formatting to manage, especially in the context of a macro. The heart of the problem is that an explicit attribute like "No Super/Sub" is technically not the same thing as a lack of any super/sub formatting. They may appear the same in the text and on the menu, but one is the default/neutral state while another is an explicit override.

This kind of formatting is usually desirably discarded when copy/pasting or saving/opening files, in situations where it is irrelevant to the correct display of text. This makes it difficult to persist in macro code. The formatting may be superfluous for the correct display of the text, but obviously you need it for your macro code. You need to do extra work so Nisus Writer cannot discard the formatting as superfluous. Usually you do this by creating a superscripted style which your text's formatting overrides. Then this "No Super/Sub" formatting is important and Nisus cannot discard it.

However, this approach is convoluted. And it may still be brittle with respect to formatting-sensitive search. I much prefer an explicit tactic for macro code like filtering out all superscripted text:

Code: Select all

# Find All
If ! Find @Text<(–[\d])>, 'Ea'
	Prompt "There are no matches."
	Exit
End

# Remove selections that contains super/sub-scripted text
$doc = Document.active
$selections = $doc.textSelections
$newSelections = Array.new
ForEach $selection in $selections
	# check if this selection has any super/sub
	$hasSuperscript = @false
	$text = $selection.text
	$scanAt = $selection.location
	While $scanAt < $selection.bound
		$attrs = $text.displayAttributesAtIndex($scanAt)
		If $attrs.superscript != 0
			$hasSuperscript = @true
		End
		$scanAt = $text.rangeOfDisplayAttributesAtIndex($scanAt).bound
	End
	# only include selections without any super/sub
	If ! $hasSuperscript
		$newSelections.appendValue($selection)
	End
End

# apply filtered selections
If $newSelections.count == 0
	Prompt "There are no matches without super/sup-script."
	Exit
End
$doc.setSelection($newSelections)

# replace in selections
Find and Replace @Text<(–[\d])>, @Text<\1>, 'Eas'
I left your final Find/Replace statement as-is, but as written it does nothing. So either that's a mistake in your expression or you intend to only change the formatting of the matches. If the latter is true then I suggest you do not use Find/Replace for the task. Instead just apply the formatting to the already found/selected text.
davidmacd
Posts: 6
Joined: 2003-06-12 10:14:22
Location: SCOTLAND

Re: Find and replace using attributes works, but macro doesn't

Post by davidmacd »

Thanks for replying in depth. I will look at this tomorrow, as it's late night here now.

Yes, the macro expressions in my initial post are incorrect (typed in haste rather than pasted). However, by the time I posted I was pretty certain that the replacement using a macro wasn't working whereas the Find and Replace was.

What I'm attempting to do is differentiate between strings such as 'interleukin–2', where the documents concerned wrongly have an en dash rather than a hyphen, which is correct in that sort of expression, and strings such as x–2, where the –2 is superscript (i.e. x to the power of minus 2), and where the requirement is to adopt an en dash as a minus sign. Both strings have a character in the range a-z followed by an en dash followed by a digit. The difference lies in the superscript applied. I wanted to change only those that had no superscript applied.

Thank you again for replying.
adryan
Posts: 563
Joined: 2014-02-08 12:57:03
Location: Australia

Re: Find and replace using attributes works, but macro doesn't

Post by adryan »

G'day, davidmacd et al

Maybe an easier solution would be to replace all your en dashes with hyphens, then replace just the hyphens in your superscripts with en dashes.

You don’t need any fancy F/R expressions for this. The first part is simple. For the second part, you apply the Superscript command from the Format menu (under Baseline) to your “.+” in the Find field, find all your superscripts, then do a Find & Replace In Selection to replace the hyphens with en dashes.

Cheers,
Adrian
MacBook Pro (M1 Pro, 2021)
macOS Ventura
Nisus Writer user since 1996
davidmacd
Posts: 6
Joined: 2003-06-12 10:14:22
Location: SCOTLAND

Re: Find and replace using attributes works, but macro doesn't

Post by davidmacd »

Thanks for your reply, Adryan.

The method you suggest would be a solution if only the documents concerned didn't contain so many valid en dashes, even in normal (baseline) text. Unfortunately, they do, for example where ranges of pages are cited, for example 'see pages 24–41', or in expressions such as 'North–South divide', and so on. There are many, a great many, cases where en dashes must remain (in fact more than need targeted for replacement). The easier software solution seemed to be to exclude superscript (I will reflect on that again though).

I am up against another problem, more people-related than anything else. I like the power of regex and macros, where Nisus can generally trump software such as MS Word. However, colleagues are familiar with MS Word and are reluctant to change. The find and replace that started this thread can be done in MS Word, where an attribute like superscript can be easily excluded in order to to restrict the replacement, and an equivalent macro generated as well. The so-called wildcard find and replace in MS Word is a shadow of what can be done with full regex, but there are cases where it can deliver an easier solution. That is the real problem I have to solve: persuading people who may be experts in a different fields, e.g. biochemistry, to adopt powerful grep software such as Nisus when I can't demonstrate a solution that they will consider 'easy' to adopt when compared with what they already do in MS Word. I am working on explaining that the pluses will outweigh the minuses, but that isn't obvious to everyone.

Thank you again.
adryan
Posts: 563
Joined: 2014-02-08 12:57:03
Location: Australia

Re: Find and replace using attributes works, but macro doesn't

Post by adryan »

G'day, davidmacd et al

First, I generally advise people considering extensive Find & Replace operations to know the contents of their document first. Obviously you do, as you are aware of multiple legitimate uses of en dashes in your document that mean that my simple offering will not suffice in its stated form. (I mention this business of knowing one's document, just to emphasize to others how important it is.)

Next, it gladdens my antipodean heart to see your examples of en dashes in action. Most people would just use hyphens in their stead.

Finally, how about this approach? Use the method in my previous posting to find all your superscripts. Then File > Select > Invert Selection. And then use appropriate Find and Replace expressions to Replace In Selection just the errant en dashes with hyphens, without interfering with your superscripts. This could easily be Macroized to impress your MS Word "friends". I won't do it here because I do not know what complexities your document contains.

Cheers,
Adrian
MacBook Pro (M1 Pro, 2021)
macOS Ventura
Nisus Writer user since 1996
adryan
Posts: 563
Joined: 2014-02-08 12:57:03
Location: Australia

Re: Find and replace using attributes works, but macro doesn't

Post by adryan »

G'day, davidmacd et al

Again, knowing your document is crucial.

It occurs to me that there may even be some relatively obvious distinction between your superscripts and the rest of the content that you could exploit.

For example, you've been searching for every formatting-sensitive occurrence of an en dash followed by a digit, whereas maybe you should be searching for every (formatting-insensitive) occurrence of an en dash preceded by two or more lowercase letters and followed by a digit. That would pick up your chemical names without also picking up your negative ionic charges in chemical formulae or negative exponents.

Cheers,
Adrian
MacBook Pro (M1 Pro, 2021)
macOS Ventura
Nisus Writer user since 1996
davidmacd
Posts: 6
Joined: 2003-06-12 10:14:22
Location: SCOTLAND

Re: Find and replace using attributes works, but macro doesn't

Post by davidmacd »

... maybe you should be searching for every (formatting-insensitive) occurrence of an en dash preceded by two or more lowercase letters and followed by a digit.
That could work in some contexts, although knowing the subject matter I think I would have to search for at least three or more letters, and both lower and upper case, followed by an en dash and a digit. Such en dashes could, I think, be safely replaced with hyphens. I will reflect further.
That would pick up your chemical names without also picking up your negative ionic charges in chemical formulae or negative exponents.
At the moment I'm concerned only with negative exponents – ions either have a plus or minus sign (no superscript digit at all) or the superscript digit precedes the superscript plus or minus sign (en dash), e.g. Cl– or O2– or Fe3+ – these I intend to handle separately. But, yes, they can also pose tricky situations.

Thank you again for engaging in this.

And thank you, Martin, for the code you supplied and for this explanation:
The heart of the problem is that an explicit attribute like "No Super/Sub" is technically not the same thing as a lack of any super/sub formatting. They may appear the same in the text and on the menu, but one is the default/neutral state while another is an explicit override.
That helped with my mental model of what is going on behind the scenes. There is clearly a difference between what Find and Replace does and the apparently equivalent macro. I didn't quite appreciate just how much. Thanks.
User avatar
martin
Official Nisus Person
Posts: 5228
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

Re: Find and replace using attributes works, but macro doesn't

Post by martin »

davidmacd wrote: 2023-02-14 02:34:18 I am up against another problem, more people-related than anything else. I like the power of regex and macros, where Nisus can generally trump software such as MS Word. However, colleagues are familiar with MS Word and are reluctant to change.
This is always a tough nut to crack. Word definitely has the advantage of being entrenched.

I'm sorry this particular search scenario had some snags in Nisus Writer. The macro-ization of formatting-sensitive searches that employ the use of negative attributes like "not superscript" is unfortunately a rough edge in the Nisus macro language. It would be nice if we could improve the handling of such formatting so it is retained more readily by macro documents.

The current behavior is inherited from what users expect when editing normal documents. Usually a person does not want to retain "not superscript" or "not bold" in their text unless it overrides a style. This behavior actually makes the most sense even for positive formatting. For example: there is no desire to retain manual formatting that specifies a font size of 12 points if it's already enforced by the Normal style.
That helped with my mental model of what is going on behind the scenes. There is clearly a difference between what Find and Replace does and the apparently equivalent macro. I didn't quite appreciate just how much. Thanks.
I'm very happy the explanation helped!
Post Reply