Reputation: 13226
I need to take an input from a WYSIWYG and break it down to having 33 (or approximate) characters per line. If it hits the limit, I need to insert a new line. Here is what I came up with:
for($i=0; $i < strlen($string); $i++) {
if ($i % 33 == 0 && $i != 0) {
$characters[] = '\r';
}
$characters[] = $string[$i];
}
$result = implode($characters);
This breaks HTML tags and words. I need to ignore HTML tags, and allow words to finish before breaking a line. What is a better way to achieve this?
Upvotes: 0
Views: 831
Reputation: 2376
What I would do is explode by space, then figure out the number of "words" that can fit on a line without going over 33 characters.
$words = explode(' ', $string); // Get all the "words" into one string
$lines = array(); // Array of the lines
$line = array(); // One line
for ($i = 0; $i < count($words); $i++) {
$new_line = array_merge($line, $words[$i]); // Previous line plus this word
$new_line_length = strlen(strip_tags(implode(' ', $new_line))); // Length of line
if ($new_line_length <= 33) { // Is this line under 33 characters?
$line[] = $words[$i]; // Yes, let's add this word to the line
} else { // No, too long.
$line[] = "\r"; // Add newline
$lines[] = $line; // Add $line to the $lines array
$line = array(); // Reset the line
}
}
$final_string = implode('', $lines); // Put the whole thing back into one string
I just did this in here and haven't tested it, but it's the basic general idea. Hope it helps. Good luck. :)
Edit: added strip_tags() to the length check so tags won't affect the length of the line (since they're invisible anyway)
Upvotes: 1
Reputation: 57719
I've found that JavaScript is actually very good at this because you have the power of the DOM available. You can just ask "how wide is this piece of tekst", which takes individual character widths into account.
The overall idea is:
div
) or an inline element (like span
or a
). For block level elements: assume they will begin on a new line and end with a new line, so reset your counters accordingly.Upvotes: 0