Function proposal: nl2p

From: Date: Sun, 07 Mar 2004 18:07:08 +0000
Subject: Function proposal: nl2p
Groups: php.internals 
Request: Send a blank email to internals+get-8421@lists.php.net to get a copy of this message
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 <br /> tag does not have as much possibilities as the <p> 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 </p>\n<p> before matched regexp \n\r?|\r\n? , <p> before the string and </p> 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</p>\n<p>") - 1) + sizeof("\n<p>\n") + sizeof("\n</p>"); 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 ---

« previous php.internals (#8421) next »