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

Reply via email to