0
votes

I'm trying to insert a link in TLF. Normally you would simply simply use

var linkElement:LinkElement = textArea.textFlow.interactionManager.applyLink( ... );

The problem is that, if I create a link which spans across differently formatted text (bold, italic, etc), or heaven forbid across paragraphs and list items, it completely and utterly crashes and burns. Link formatting is completely lost, and list structures collapse.

Simply adding a LinkElement via addChild() doesn't work either, if we're going to keep both the formatting and the structure within the selected text.

Ripping out the textFlow for the selection with interactionManager.cutTextScrap(...), wrapping it in a LinkElement with interactionManager.applyLink( ... ), and then "pasting" back in... also creates a mess.

So I have to create my own link insertion routine.

What I've resolved to do is to:

1) convert the textflow tags to a string

2) find the start and end indexes of the selection within the textflow string

3) insert the following string at the start index:

</span><a href="[hrefVar]" target="[targetVar]"><span>

4) insert the following string at the end index:

</span></a><span>

5) reconvert the textflow string into a textflow object for the TextArea

And voila! Instant RTF link!

The only problem is... I have no idea how to write a regex parsing equation which can find the start and ending indexes for a string match inside XML markup where the result may be spread across several tags.

For instance, if the TextFlow is (abbreviated):

<TextFlow><p><span>Lorem Ip</span><span fontWeight="bold">sum do</span><span>
lor sit am</span><span fontStyle="italic">et, consectetur adipiscing elit.
</span></p></TextFlow>

Say, for instance, the user has selected "Ipsum dolor sit amet" to be converted into a link. I need to find the first and last indexes of "Ipsum dolor sit amet" within that RTF markup, and then insert the strings indicated in 3) & 4) above, so that the end result looks like this:

<TextFlow><p><span>Lorem </span><a href="http://www.google.ca" target="_blank">
<span>Ip</span><span fontWeight="bold">sum do</span><span>lor sit am</span>
<span fontStyle="italic">et</span></a><span>, consectetur adipiscing elit.
</span></p></TextFlow>

You might lose some style formatting, but I can fix that later parsing through the textflow formatting.

What I need is the regex to do step 2).

I know the regex to ignore tags and strip out the text between tags, and how to find a string match of the selected text in the stripped textflow text... but not how to find the match indexes within the original (unstripped) textflow string.

Anyone?

1

1 Answers

0
votes

IMHO better way is to go through out the string instead of trying to go with regex. Here is an idea for quick dirty way, this code need to be improved, but anyway it might give directions. So main goal might be just "throw out" tags and match text, but counting gow many chars passed within the process.

//This code might need revision for not to get < and > symbols as fake tags starting and finishing points, also reseting searchwhen text not completly done. 

var sourceStr:String = '<TextFlow><p><span>Lorem Ip</span><span fontWeight="bold">sum do</span><span>lor sit am</span><span fontStyle="italic">et, consectetur adipiscing elit.</span></p></TextFlow>';
var searchStr:String = "Lorem Ipsum d";
var indexes:Object = firstLast(sourceStr, searchStr);

trace(indexes.startIndex,indexes.finishIndex);


function firstLast(sourceStr:String, searchStr:String):Object 
{
    var indexCounter:int = -1;

    var searchFlag:Boolean = true;
    var searchPos:int = 0;

    var searchChar:String;
    var sourceChar:String;

    var startIndex:int;
    var finishIndex:int;

    for (var i:int = 0; i < sourceStr.length; i++ )
    {
        indexCounter++;


        sourceChar = sourceStr.substr(i, 1);
        if (sourceChar == "<")
        {
            searchFlag = false;

        } 
        else if (sourceChar == ">")
        {
            searchFlag = true;
        }

        if (!searchFlag) 
        {
            continue;
        }

        searchChar = searchStr.substr(searchPos, 1);    
        if (sourceChar == searchChar)
        {
            if (searchPos == 0)
            {
                startIndex = indexCounter;
            }
            if (searchPos == searchStr.length - 1)
            {
                finishIndex = indexCounter;
            }
            searchPos++;
        }


    }

    return { startIndex:startIndex, finishIndex:finishIndex };

}