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