Jump to content

Recommended Posts

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);
}

Link to comment
https://forums.phpfreaks.com/topic/108001-solved-recursive-function-help/
Share on other sites

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;
}
?>

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;
}

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

 

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...

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  

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.