## rangeOfAttributesAtIndex

Get help using and writing Nisus Writer Pro macros.
Nobumi Iyanaga
Posts: 151
Joined: 2007-01-17 05:46:17
Location: Tokyo, Japan
Contact:

### rangeOfAttributesAtIndex

Hello,

In Nisus Macro Reference, I find in the explanation for "text.rangeOfAttributesAtIndex" a sentence saying:

This range is not necessarily the longest (maximal) range over which attributes are equal, eg: text adjacent to the returned range could have the same attributes.

What does this mean in practice? For example, given a document, isn't it possible to get all the ranges of all the pieces of text differently formatted? For example with a code like the following:

Code: Select all

$doc = Document.active$text = $doc.text$charIndex = 0
$limit =$text.length
$ranges = Array.new # inspect the attributes applied to every character in the text While$charIndex < $limit$range = $text.rangeOfDisplayAttributesAtIndex($charIndex)
$ranges.push ($range)

$charIndex =$range.bound
End 
Best regards,

Nobumi Iyanaga
Tokyo,
Japan

martin
Official Nisus Person
Posts: 4261
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

### Re: rangeOfAttributesAtIndex

I think that you understand the technical definition, but all the same I want to make it clear. That range returned by the command could cover only part of the text that appears to the user to have the same formatting. For example, consider the text: "bold text run". The range returned when inspecting index zero could cover only the word "bold" and not necessarily the entire bolded text "bold text".

In practice this could occur for a variety of reasons that would probably not be clear to a macro author. For example, when a paragraph is marked for inclusion in a TOC an invisible/internal attribute is added that tracks the content in the document. This would limit the range of the returned attributes to a single paragraph, even if multiple adjacent paragraphs have exactly the same formatting.

Basically if exact detection of attribute changes is important to the correct functioning of your macro it would be best for your code to compare the attribute value(s) you are interested in. Hopefully this explanation is helpful.

Nobumi Iyanaga
Posts: 151
Joined: 2007-01-17 05:46:17
Location: Tokyo, Japan
Contact:

### Re: rangeOfAttributesAtIndex

Hello Martin,

Thank you for your reply. So, if I understand well, this means that "rangeOfAttributesAtIndex" returns, if not the maximum, at least the minimum length of a text having the same attributes, is this right?

Thank you.
Best regards,

Nobumi Iyanaga
Tokyo,
Japan

martin
Official Nisus Person
Posts: 4261
Joined: 2002-07-11 17:14:10
Location: San Diego, CA
Contact:

### Re: rangeOfAttributesAtIndex

I'm not sure I understand your question. The "minimal" range of would always have a length of one character, would it not? The only thing that rangeOfAttributesAtIndex guaranties is that the attributes over the range are equal. There may be adjacent characters with the same visible attributes or not.

Nobumi Iyanaga
Posts: 151
Joined: 2007-01-17 05:46:17
Location: Tokyo, Japan
Contact:

### Re: rangeOfAttributesAtIndex

Hello Martin,

I'm sorry, my question was not well formulated.
The only thing that rangeOfAttributesAtIndex guaranties is that the attributes over the range are equal. There may be adjacent characters with the same visible attributes or not.
I understood, and this is what I wanted to know. Thank you!
Best regards,

Nobumi Iyanaga
Tokyo,
Japan

Kino
Posts: 400
Joined: 2008-05-17 04:02:32

### Re: rangeOfAttributesAtIndex

I think the main problem is that it is a bit difficult to get a continuous range of a specific attribute when there are text portions in mixed attributes. For example, the following macro will transform "abcdefghi" into "\textit{abc}\textit{def}\textit{ghi}" which is not desirable for a macro converting style attributes into tags used in LaTeX, html, etc.

Code: Select all

$prefix = Cast to String '\textit{'$suffix = Cast to String '}'
Require Application Version 3.1
$doc = Document.active$selections = Array.new
$textObjects =$doc.allTexts

foreach $text in$textObjects
if $text.length$index = 0
$limit =$text.length
while $index <$limit
$attr =$text.displayAttributesAtIndex $index$range = $text.rangeOfDisplayAttributesAtIndex$index
$isItalic =$attr.italic
if $isItalic == true$sel = TextSelection.new $text,$range
$selections.appendValue$sel
end
$index =$range.bound
end
end
end

foreach $sel in reversed$selections
$sel.text.insertAtIndex$sel.bound, $suffix$sel.text.insertAtIndex $sel.location,$prefix
end

To get "\textit{abcdefghi}", you have to add something which merges text selection objects (I don't know if "merge" is the right word).

Code: Select all

$i =$selections.count - 1
while $i > 0$sel = $selections[$i]
$selBefore =$selections[$i-1] if$sel.text == $selBefore.text if$sel.location == $selBefore.bound$selBefore.length += $sel.length$selections.removeValueAtIndex $i end end$i -= 1
end

It works but it would be very nice if a future version of Nisus Writer Pro will have a macro command such as \$selections.merge or something alike.

Thanks! ;-)

Edit: I corrected a bug in the macro by replacing "rangeOfAttributesAtIndex" with "rangeOfDisplayAttributesAtIndex".