c-drive Posted May 30, 2008 Share Posted May 30, 2008 I'm working on a recursive function that basically performs a simple 'word wrap' after a given number of characters. Given a string, an array and a the number of characters you want per line, this function should split up the string and return an array of 'lines'. It's not returning anything -- I believe that I'm having some trouble with keeping track of the array, related to passing by reference (or not). Any help is greatly appreciated. ??? Function: function makeWordWrap($text, $lines, $maxChars){ /* see if the text is longer than maxChars characters. If it is, find the space closest to character maxChars and split the string there */ /* do this again and again until we have an array of lines that are all maxChars or less characters long */ if(strlen($text) < $maxChars){ array_push($lines,$text); return $lines; } /* we know the text is longer than 70, so figure out how many lines we are going to need */ $currentChunk = substr($text,0,$maxChars); $lastSpace = strrpos($currentChunk," "); $currentRow = substr($text,0,$lastSpace); $text = substr($text,$lastSpace); array_push($lines,$currentRow); makeWordWrap($text,&$lines,$maxChars); } Test data: $lines = array(); $txt = "The documentation for 'offset' is misleading. It says, offset may be specified to begin searching an arbitrary number of characters into the string. Negative values will stop searching at an arbitrary point prior to the end of the string. This is confusing if you think of strrpos as starting at the end of the string and working backwards. A better way to think of offset is: If offset is positive, then strrpos only operates on the part of the string from offset to the end. This will usually have the same results as not specifying an offset, unless the only occurences of needle are before offset (in which case specifying the offset won't find the needle). If offset is negative, then strrpos only operates on that many characters at the end of the string. If the needle is farther away from the end of the string, it won't be found. If, for example, you want to find the last space in a string before the 50th character, you'll need to do something like this.--------------------------"; print_r(makeWordWrap($txt,$lines,70)); function makeWordWrap($text, $lines, $maxChars){ /* see if the text is longer than maxChars characters. If it is, find the space closest to character maxChars and split the string there */ /* do this again and again until we have an array of lines that are all maxChars or less characters long */ if(strlen($text) < $maxChars){ array_push($lines,$text); return $lines; } /* we know the text is longer than 70, so figure out how many lines we are going to need */ $currentChunk = substr($text,0,$maxChars); $lastSpace = strrpos($currentChunk," "); $currentRow = substr($text,0,$lastSpace); $text = substr($text,$lastSpace); array_push($lines,$currentRow); makeWordWrap($text,&$lines,$maxChars); } Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/ Share on other sites More sharing options...
rarebit Posted May 30, 2008 Share Posted May 30, 2008 Take a look at this instead.... Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/#findComment-553553 Share on other sites More sharing options...
c-drive Posted May 30, 2008 Author Share Posted May 30, 2008 Thanks, I guess I could just explode against '\n', but it will still make me angry that my original function doesn't work... Cheers Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/#findComment-553556 Share on other sites More sharing options...
sasa Posted May 30, 2008 Share Posted May 30, 2008 try <?php $lines = array(); $txt = "The documentation for 'offset' is misleading. It says, offset may be specified to begin searching an arbitrary number of characters into the string. Negative values will stop searching at an arbitrary point prior to the end of the string. This is confusing if you think of strrpos as starting at the end of the string and working backwards. A better way to think of offset is: If offset is positive, then strrpos only operates on the part of the string from offset to the end. This will usually have the same results as not specifying an offset, unless the only occurences of needle are before offset (in which case specifying the offset won't find the needle). If offset is negative, then strrpos only operates on that many characters at the end of the string. If the needle is farther away from the end of the string, it won't be found. If, for example, you want to find the last space in a string before the 50th character, you'll need to do something like this.--------------------------"; print_r(makeWordWrap($txt, 70)); function makeWordWrap($text, $maxChars){ /* see if the text is longer than maxChars characters. If it is, find the space closest to character maxChars and split the string there */ /* do this again and again until we have an array of lines that are all maxChars or less characters long */ if(strlen($text) < $maxChars){ return array($text); } /* we know the text is longer than 70, so figure out how many lines we are going to need */ $currentChunk = substr($text,0,$maxChars); $lastSpace = strrpos($currentChunk," "); $currentRow = substr($text,0,$lastSpace); $text = substr($text,$lastSpace); $out = array_merge(array($currentRow), makeWordWrap($text,$maxChars)); return $out; } ?> Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/#findComment-553566 Share on other sites More sharing options...
rarebit Posted May 30, 2008 Share Posted May 30, 2008 Somehow this just feels wrong? $txt = "The documentation for 'offset' is misleading. It says, offset may be specified to begin searching an arbitrary number of characters into the string. Negative values will stop searching at an arbitrary point prior to the end of the string. This is confusing if you think of strrpos as starting at the end of the string and working backwards. A better way to think of offset is: If offset is positive, then strrpos only operates on the part of the string from offset to the end. This will usually have the same results as not specifying an offset, unless the only occurences of needle are before offset (in which case specifying the offset won't find the needle). If offset is negative, then strrpos only operates on that many characters at the end of the string. If the needle is farther away from the end of the string, it won't be found. If, for example, you want to find the last space in a string before the 50th character, you'll need to do something like this.--------------------------"; //$txt = "The documentation for 'offset' is misleading"; $l = makeWordWrap($txt,array(),70); foreach($l as $e) { print $e."<br><br>"; } function makeWordWrap($text, $lines, $maxChars) { while(strlen($text) > $maxChars) { $lines[] = substr($text,0,$maxChars); $text = substr($text,$maxChars); makeWordWrap($text,$lines,$maxChars); } $lines[] = $text; return $lines; } Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/#findComment-553576 Share on other sites More sharing options...
c-drive Posted May 30, 2008 Author Share Posted May 30, 2008 Thanks sasa and rarerabit for the help! Both solutions worked: sasa, do you know why the array wasn't passed without using array_merge? rarerabit, your solution looks like the most elegant by removing some of the funcitons I was using, but it doesn't split at the space closest to character X, just at the character, so it doesn't work too well for word wrapping . In any event, it helped me get beyond the array sticking point. Thanks again Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/#findComment-553703 Share on other sites More sharing options...
rarebit Posted May 30, 2008 Share Posted May 30, 2008 Knew I wasn't happy... function makeWordWrap($text, $lines, $maxChars) { if(strlen($text) > $maxChars) { $lines[] = substr($text,0,$maxChars); $text = substr($text,$maxChars); $lines = makeWordWrap($text,$lines,$maxChars); } else { $rem = strlen($text) % $maxChars; $lines[] = substr($text,-$rem); } return $lines; } This version does what you want, but I think that every now and again it'll be wrong... err! function makeWordWrap($text, $lines, $maxChars) { if(strlen($text) > $maxChars) { $pos = strpos($text," ", $maxChars); $lines[] = substr($text,0,$pos); $text = substr($text,$pos); $lines = makeWordWrap($text,$lines,$maxChars); } else { $rem = strlen($text) % $maxChars; $lines[] = substr($text,-$rem); } return $lines; } The next problem is that any html is counted but not drawn on the line... Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/#findComment-553780 Share on other sites More sharing options...
c-drive Posted June 1, 2008 Author Share Posted June 1, 2008 Thanks all for your help. I finally figured it out with some help from your examples. I wasn't re-setting the lines array and I wasn't returning the results back into the recursive calls. In case anyone is interested: function makeWordWrap($text, $lines, $maxChars){ /* see if the text is longer than maxChars characters. If it is, find the space closest to character maxChars and split the string there */ /* do this again and again until we have an array of lines that are all maxChars or less characters long */ if(strlen($text) < $maxChars){ array_push($lines,$text); return $lines; } /* we know the text is longer than 70, so figure out how many lines we are going to need */ $currentChunk = substr($text,0,$maxChars); $lastSpace = strrpos($currentChunk," "); $currentRow = substr($text,0,$lastSpace); $text = substr($text,$lastSpace); array_push($lines,$currentRow); $lines = makeWordWrap($text,$lines,$maxChars); return $lines; } Cheers Quote Link to comment https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/#findComment-554622 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.