stringactionscript-3functionstring-utils

Break a string in substrings (lines) without split words


i'm working in a small function that should break a string in substrings making sure that none of words will be cutted.

Let's get this use case:

"something is going wrong and i can't figure out what's the problem"

total characters: 63;

with a max chars length of 15 per line i would get this substr "something is go"

as you can see it is cutting the word when i would like to get the entire word.

line[1]: something is //break the string on the last space bellow the max chars length;

line[2]: going wrong .... //includes's the missing characters from the first line at the begining of the second line

line[3]: .... //and so on until all the characters get looped.

I come up with this solution which is driving me crazy.

function splitString(obj:Object):Array{

if (obj.hasOwnProperty("d_string"))
{
    var texto:String = obj.d_string;

    var textoStr:Array = texto.split("");
    var textoLen:Number = texto.length;
    trace("textoLen " + textoLen);

    var maxCharPerLine:Number;
    if (obj.hasOwnProperty("d_limit")){
        maxCharPerLine = obj.d_limit;
        trace("maxCharPerLine" + maxCharPerLine);
    }else{
        maxCharPerLine = 20;
    }


    var textLine:Array = [];

    var currentLine:Number = 1;
    var currentIndex:Number = 0;


    var cachedCharsForLine:Array = [];      //all characters between the range
    var lastCachedCharsForLine:Array = [];  //mirror of all characters stoping at the last space found
    var missingChars:Array = [];


    var canCleanData:Boolean = false;



    /*START LOOPING OVER THE STRING*/   
    for (var i:Number = 0; i< textoLen; i++) 
    {   
        //<block1>
        if ( currentIndex == maxCharPerLine || i == textoLen -1 ){ 
            canCleanData = true;
        }
        //<block2> 22
        if ( currentIndex <= maxCharPerLine ){ 
            cachedCharsForLine.push(textoStr[i]);
            //trace(cachedCharsForLine);
        }



            trace(textoStr[i]);
            trace(textoStr[i] == " ");


            /*is the characters a space?*/
            if (textoStr[i] == " ") {
                /*1. even after the condition above returns false*/
                lastCachedCharsForLine = [];
                lastCachedCharsForLine = cachedCharsForLine;
            }


            /*as you can see from the output this value is being updated every iteration after the first space get found
            when it was suppose to be updated only if the a char of type <space> get found"
            */
            trace("-----------------" + lastCachedCharsForLine)


        //<block4>
        if( currentIndex == maxCharPerLine || i == textoLen -1 ){       

            if (textoStr[i]==" " || textoStr[i+1]==" "){        
                trace("\n A");
                //trace("@@@      " + lastCachedCharsForLine);
                textLine[currentLine] = lastCachedCharsForLine;
                trace("//" + textLine[currentLine]);
            }
            else{
                trace("\n B");
                //trace("@@@      " + lastCachedCharsForLine);
                textLine[currentLine] = lastCachedCharsForLine;
                trace("//" + textLine[currentLine]);
            }

            currentIndex = 0;
            currentLine ++;
        }

        //<block5>
        if (currentLine > 1 && canCleanData){
            trace("DATA CLEANED");
            canCleanData = false;
            cachedCharsForLine = [];
            lastCachedCharsForLine = [];
        }

        currentIndex ++;
    }
    return textLine;
}else{
    return textLine[0] = false;
}

}



var texto:String = "Theres something going wrong and it's driving me crazy.";
var output:Array = []
output = splitString({"d_string":texto,"d_limit":15});

for (var i:Number = 0; i<output.length; i++){
    trace(output[i] + "\n\n");  
}

lastCachedCharsForLine's variable is being updated as you can see from this trace line.

trace("-----------------" + lastCachedCharsForLine)

even with the condition bellow returning false

 if (textoStr[i] == " ") {
                    /*1. even after the condition above returns false*/
                    lastCachedCharsForLine = [];
                    lastCachedCharsForLine = cachedCharsForLine;
                }

Solution

  • That was kinda fun. Code below outputs:

    |-------------|
    something is
    going wrong
    and i can't
    figure out
    what's the
    problem.
    WORDTHATISWAYTOOLONGFORTHEBUFFER.
    A quick brown
    fox jumped
    over the lazy
    dog.
    
    package {
    
        import flash.display.Sprite;
    
        final public class Test2 extends Sprite {
    
            public function Test2() {
    
                splitIntoLines("something is going wrong and i can't figure out what's the problem.  WORDTHATISWAYTOOLONGFORTHEBUFFER. A quick brown fox jumped over the lazy dog.");
    
            }
    
            private function splitIntoLines(text:String, maxLineLength:int = 15):void {
                const words:Array   = text.split(/\s+/);
                const output:Array  = [];
    
                var buffer:String   = '';
                while (words.length) {
    
                    var word:String = words.shift() as String;
    
                    // if buffer has something, add a space
                    if (buffer.length) {
    
                        if (buffer.length + word.length + 1 < maxLineLength) {
                            buffer += ' ' + word;
                        } else {
                            output.push(buffer);
                            buffer = word;
                        }
    
                    // otherwise, it's the first word
                    } else {
    
                        if (buffer.length + word.length < maxLineLength) {
                            buffer += word;
                        } else {
                            output.push(buffer);
                            buffer = word;
                        }
                    }
                }
    
                // something is still in there?
                if (buffer.length) {
                    output.push(buffer);
                }
    
                trace(output.join('\n'));
    
            }
        }
    }