Skip to main content
Inspiring
November 4, 2009
Answered

Textflow substring

  • November 4, 2009
  • 1 reply
  • 817 views

I would like to get a plain text string representation of a TextFlow from indexA to indexB.  I don't want to effect the current selection.

For example I want to listen to the TextFlow changes and on each change parse the text that the user has entered for certain keywords - ideally only the text they have just entered - not the entire TextFlow. I am using EditManager, and can see the last index of the begining of the last word for example, but I can't understand how to actually get the word as a string without cycling over it character by character. I thought of trying to use TextRange -> TextScrap -> export but that will tamper with the user's selection. 

As this is something I would like to do on every FlowOperationEvent, it would be good if it isn't too CPU intensive!

Thanks for any thoughts.

This topic has been closed for replies.
Correct answer robin_briggs

I'd suggest you write some code to get the text yourself, that will be more efficient than any other method. You can get the text of a paragraph by calling getText() on the ParagraphElement. I would guess that you might want something like this:

var copyLength:int = endOfRange - startOfRange;

var text:String;

var pos:int = startOfRange;

while (pos < endOfRange)

{

     var leaf:FlowLeafElement = textFlow.findLeaf(pos);

     p = leaf.getParagraph();

     amtToCopy:int = Math.max(copyLength, p.textLength-1);

     if (pos == startOfRange)

          text = p.getText().substr(pos - p.getAbsoluteStart(), amtToCopy);

     else if (pos + amtToCopy >= endOfRange)

          text = p.getText().substr(0, amtToCopy);

     else

          text += p.getText();

    pos += p.textLength;

    copyLength -= amtToCopy;

   if (amtToCopy > 0)

          text += "\n";

}

Coded that up on the fly, so I suspect there's some debugging involved. The basic principle is to iterate through all the paragraphs, the partial first, all the middle ones, and the partial last, and getting the text of the paragraph, plus a newline at the end of the paragraph. I would start by trying this, and see how it does.

Hope this helps,

- robin

1 reply

robin_briggsCorrect answer
Adobe Employee
November 4, 2009

I'd suggest you write some code to get the text yourself, that will be more efficient than any other method. You can get the text of a paragraph by calling getText() on the ParagraphElement. I would guess that you might want something like this:

var copyLength:int = endOfRange - startOfRange;

var text:String;

var pos:int = startOfRange;

while (pos < endOfRange)

{

     var leaf:FlowLeafElement = textFlow.findLeaf(pos);

     p = leaf.getParagraph();

     amtToCopy:int = Math.max(copyLength, p.textLength-1);

     if (pos == startOfRange)

          text = p.getText().substr(pos - p.getAbsoluteStart(), amtToCopy);

     else if (pos + amtToCopy >= endOfRange)

          text = p.getText().substr(0, amtToCopy);

     else

          text += p.getText();

    pos += p.textLength;

    copyLength -= amtToCopy;

   if (amtToCopy > 0)

          text += "\n";

}

Coded that up on the fly, so I suspect there's some debugging involved. The basic principle is to iterate through all the paragraphs, the partial first, all the middle ones, and the partial last, and getting the text of the paragraph, plus a newline at the end of the paragraph. I would start by trying this, and see how it does.

Hope this helps,

- robin

josh_onAuthor
Inspiring
November 4, 2009

Thanks!

I have worked on it a bit - and wrapped it in a class, this will need more testing - but maybe it will be useful for someone else too:

package

{

import flashx.textLayout.elements.FlowLeafElement;

import flashx.textLayout.elements.ParagraphElement;

import flashx.textLayout.elements.TextFlow;

public class TextLayoutUtil

{

public static function getSubString(textFlow:TextFlow, startOfRange:int, endOfRange:int):String {

var text:String = "";

var pos:int = startOfRange;

while (pos < endOfRange)

{

var leaf:FlowLeafElement = textFlow.findLeaf(pos);

var p:ParagraphElement = leaf.getParagraph();

var p_start:int = pos - p.getAbsoluteStart(); //the index of the first character to get in the current para

var amtToCopy:int = Math.min(endOfRange - pos, p.textLength - 1 - p_start);

var t:String = "";

if (pos == startOfRange){

// the first para - may be a fragment

t = p.getText().substr(p_start, amtToCopy);

} else if (pos + amtToCopy < endOfRange){

// a middle para - take whole thing

t = p.getText();

} else {

// the last para - may be a fragment

t = p.getText().substr(0, amtToCopy);

}

text += t;

pos += t.length;

if (pos <  endOfRange){

text += "\n";

pos++

}

}

return text;

}

}

}