Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:8421 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 59661 invoked by uid 1010); 7 Mar 2004 18:10:50 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 59617 invoked by uid 1007); 7 Mar 2004 18:10:50 -0000 To: internals@lists.php.net Message-ID: <404B64CC.5070108@sympatico.ca> Date: Sun, 07 Mar 2004 13:07:08 -0500 User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040203 X-Accept-Language: fr-ca, en-us, en MIME-Version: 1.0 CC: Louis-Philippe Huberdeau Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Posted-By: 69.157.229.29 Subject: Function proposal: nl2p From: lphuberdeau@sympatico.ca (Louis-Philippe Huberdeau) I wrote this very simple function (modification from nl2br actually) to convert newlines to well formatted HTML paragraphs instead of line breaks, allowing better formatting of a dynamic output. It's not the most perfect piece of code ever written, but it works and it can be quite useful. The
tag does not have as much possibilities as the

tag when it comes to CSS, which gave me the idea to write this function. -- Louis-Philippe Huberdeau --- BEGIN --- /* {{{ proto string nl2p(string str) Converts newlines to HTML paragraphs for standard compliance */ PHP_FUNCTION(nl2p) { /* in brief this inserts

\n

before matched regexp \n\r?|\r\n? ,

before the string and

after the string */ zval **zstr; char *tmp, *str; int new_length; char *end, *target; int repl_cnt = 0; int seen_other_char = 0; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &zstr) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(zstr); str = Z_STRVAL_PP(zstr); end = str + Z_STRLEN_PP(zstr); /* it is really faster to scan twice and allocate mem once insted scanning once and constantly reallocing */ while (str < end) { if( seen_other_char ) { if (*str == '\r') { if (*(str+1) == '\n') { str++; } repl_cnt++; seen_other_char = 0; } else if (*str == '\n') { if (*(str+1) == '\r') { str++; } repl_cnt++; seen_other_char = 0; } } else if( *str != '\n' && *str != '\r' ) { seen_other_char = 1; } str++; } if (repl_cnt == 0) { RETURN_STRINGL(Z_STRVAL_PP(zstr), Z_STRLEN_PP(zstr), 1); } new_length = Z_STRLEN_PP(zstr) + repl_cnt * (sizeof("\n

\n

") - 1) + sizeof("\n

\n") + sizeof("\n

"); tmp = target = emalloc(new_length + 1); str = Z_STRVAL_PP(zstr); *target++ = '\n'; *target++ = '<'; *target++ = 'p'; *target++ = '>'; *target++ = '\n'; seen_other_char = 0; while (str < end) { switch (*str) { case '\r': case '\n': if( seen_other_char ) { *target++ = '\n'; *target++ = '<'; *target++ = '/'; *target++ = 'p'; *target++ = '>'; *target++ = '\n'; *target++ = '<'; *target++ = 'p'; *target++ = '>'; if ((*str == '\r' && *(str+1) == '\n') || (*str == '\n' && *(str+1) == '\r')) { *target++ = *str++; } seen_other_char = 0; } *target++ = *str; break; default: seen_other_char = 1; *target++ = *str; } str++; } *target++ = '\n'; *target++ = '<'; *target++ = '/'; *target++ = 'p'; *target++ = '>'; *target++ = '\n'; *target = '\0'; RETURN_STRINGL(tmp, new_length, 0); } /* }}} */ --- END ---