Reply to topic  [ 6 posts ] 
rangeOfAttributesAtIndex 
Author Message

Joined: 2007-01-17 05:46:17
Posts: 145
Location: Tokyo, Japan
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:
$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


Thank you in advance.

_________________
Best regards,

Nobumi Iyanaga
Tokyo,
Japan


2008-06-25 17:07:48
Profile WWW
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
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.


2008-06-25 18:20:15
Profile WWW

Joined: 2007-01-17 05:46:17
Posts: 145
Location: Tokyo, Japan
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


2008-06-27 15:50:32
Profile WWW
Official Nisus Person
User avatar

Joined: 2002-07-11 17:14:10
Posts: 4251
Location: San Diego, CA
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.


2008-06-27 16:32:37
Profile WWW

Joined: 2007-01-17 05:46:17
Posts: 145
Location: Tokyo, Japan
Hello Martin,

I'm sorry, my question was not well formulated.

Quote:
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


2008-06-28 07:06:11
Profile WWW

Joined: 2008-05-17 04:02:32
Posts: 400
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:
$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:
$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".


2008-10-01 05:24:33
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 6 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software