Yet another refinement... This function wraps a string at a given width, but also respects embedded HTML, so HTML links are not broken. Basically, this would be a fairly drop-in replacement for the exitsing wordwrap function, with the addition of the HTMLmode parameter...
-Brad ---------------------- Start of code ---------------------- /* BF 5/24/01 ([EMAIL PROTECTED]) */ str = the string to wrap width = the width to wrap lines at newline = the string used to separate lines at the new break points hard = whether words longer than width are wrapped HTMLmode = whether to treat the text as containing HTML (entities, tags, etc) - doesn't wrap text in HTML tags - doesn't count length of HTML tags in line widths - treats HTML entities as a single character when wrapping */ PHP_FUNCTION(il_str_wrap) { zval **_str, // The string to wrap **_width = NULL, // The width to wrap lines at **_newline = NULL, // The string used to separate new lines **_hard = NULL, // Whether words longer than <width> are wrapped **_htmlmode = NULL; // Whether to use HTML mode char *newline = "\n"; // Default newline character int width = 80; // Default width int hard = 0; // Do not break words longer than width int htmlmode = 0; // Don't use HTML mode int slen; int myargc = ZEND_NUM_ARGS(); if (myargc < 1 || myargc > 5 || zend_get_parameters_ex(myargc, &_str, &_width, &_newline, &_hard, &_htmlmode) == FAILURE) { ZEND_WRONG_PARAM_COUNT(); } //if // Convert the parameters to the appropriate types convert_to_string_ex(_str); if (myargc > 1) { convert_to_long_ex(_width); width = Z_LVAL_PP(_width); if (myargc > 2) { convert_to_string_ex(_newline); newline = Z_STRVAL_PP(_newline); if (myargc > 3) { convert_to_boolean_ex(_hard); hard = Z_LVAL_PP(_hard); if (myargc > 4) { convert_to_boolean_ex(_htmlmode); htmlmode = Z_LVAL_PP(_htmlmode); } // if } // if } // if } // if slen = Z_STRLEN_PP(_str); { // Begin code block (for localized vars) int newlinelen = strlen(newline); int buffactor = (slen + newlinelen); int bufsize = buffactor * 2; char* buf = emalloc(bufsize); int buflen = 0; int newbuflen; int len; int linelen = 0; int inhtml = 0; int lwplen; char htmlend; char* str = Z_STRVAL_PP(_str); char *p, *sp, *lwp, *lastp; p = str; sp = p; lastp = str + (slen * sizeof(char)); while (sp < lastp) { if (inhtml) { if (*sp == htmlend) inhtml = 0; } else if (htmlmode && (*sp == '<')) { inhtml = 1; htmlend = '>'; } else if (htmlmode && (*sp == '&')) { inhtml = 2; htmlend = ';'; ++linelen; // Count entities as one character // Perhaps this should check for entities using a "smarter" algorithm? // This will break on some bad HTML code (ie. broken entities) } else if (*sp == '\n') { len = (sp - p) / sizeof(char); newbuflen = buflen + len + newlinelen; if (newbuflen >= bufsize) { bufsize = newbuflen + buffactor; buf = erealloc(buf, bufsize); } //if // Copy this portion in strncpy(&buf[buflen], p, len); // Copy the newline string in strcpy(&buf[buflen + len], newline); buflen = newbuflen; p = sp + sizeof(char); lwp = NULL; linelen = 0; } else { ++linelen; ++lwplen; if (isspace(*sp)) { lwp = sp; lwplen = 1; } //if if ((linelen > width) && (lwp || hard)) { char *ep; if (lwp) { ep = lwp; lwp = NULL; linelen = lwplen; } else { ep = sp; linelen = 1; } //if len = (ep - p) / sizeof(char); // Grow the buffer if needed newbuflen = buflen + len + newlinelen; if (newbuflen >= bufsize) { bufsize = newbuflen + buffactor; buf = erealloc(buf, bufsize); } //if // Copy this portion in strncpy(&buf[buflen], p, len); // Copy the newline string in strcpy(&buf[buflen + len], newline); buflen = newbuflen; p = ep; // while (isblank(*p)) // p += sizeof(char); } //if } //if sp += sizeof(char); } //while // Copy the remaining string ///////////////////////////////////// // Reallocate the buffer to the appropriate size len = slen - ((p - str) / sizeof(char)); bufsize = buflen + len; buf = erealloc(buf, bufsize + 1); // Copy the string strcpy(&buf[buflen], p); buf[bufsize] = 0; RETURN_STRINGL(buf, bufsize, 0); } //Code block } // PHP_FUNCTION(str_wrap) /* }}} */ -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php