Forum Moderators: coopster
Actually, it's not quite as simple as the title suggests....
I have user input with 'bb code' in it and need to run nl2br() over the input but leave certain sections like lists and pre-formatted areas.
Here's how I envision the proceedure:
I'm not sure where to begin? - Can anyone suggest the functions I should be using for this?
Many thanks..
Nick
Are you sure you need to worry too much?
Using your example of <ul><li> etc. etc., you should find (under the latest!DOCTYPE's) that a single <br> is ignored by browsers that interpret HTML correctly.
If you actually want a break between elements of the list you must supply 2 <br>'s....
Try it and see...
Hope this helps!
BTW why not use the code I sent you that creates P [w3.org] elements instead of using simple line breaks?
Andreas
Here it is:
[pre]
function bbcode($data) {
$data = preg_replace(array(
"'\[url=([^]]+?)\]'",
"'\[/url\]'",
"'\[url\]([^[]+?)\[/url\]'",
"'\[code\]'",
"'\[/code\]'",
"'\[q\]'",
"'\[/q\]'",
"'\[ul\]'",
"'\[/ul\]'",
"'\[li\]'",
"'\[/li\]'",
), array(
"<a href=\"\\1\">",
"</a>",
"<a href=\"$1\">\\1</a>",
"<pre><code>",
"</code></pre>",
"<q>",
"</q>",
"<ul>",
"</ul>",
"<li>",
"</li>",
), $data);
foreach(preg_split("/\n+Ķ(\r\n)+/", $data) as $token) {
if(strlen($token) == 0) continue;
if(preg_match("/^<.*>$/", $token)) { $s .= $token; continue; }
$s .= "<p>$token</p>";
}
return $s;
}[/pre]
Nick
If you add your own style codes make sure that the replacement string for those elements that are block level style elements start with a double newline for start tags and end with a double newline for end tags. That way user input like the following will be handled correctly.
[ ul ] and [ code ] are certainly meant to be block level elements. Yet their replacements do not start with a double newline nor end the end tags with a double newline. Since the preg_split [php.net] will split on a double newline and will turn the elements of the returned array into paragraph elements unless they already are other elements, i.e. they start with some tag and end with some tag.
Andreas
Here is the complete function. It now extracts <pre> text, puts in the <p>'s and then put's the <pre> text back in again:
$data = preg_replace(array( /* First get all the matches to <pre> text */ /* Replace all the <pre> text with a new string */ /* Then swap the replaced text for the original <pre> text */[pre]
function bbcode($data) {
"'\[url=([^]]+?)\]'",
"'\[/url\]'",
"'\[url\]([^[]+?)\[/url\]'",
"'\[code\]'",
"'\[/code\]'",
"'\[q\]'",
"'\[/q\]'",
"'\[ul\]'",
"'\[/ul\]'",
"'\[li\]'",
"'\[/li\]'",
"'\[em\]'",
"'\[/em\]'",
"'\[strong\]'",
"'\[/strong\]'",
), array(
"<a href=\"\\1\">",
"</a>",
"<a href=\"$1\">\\1</a>",
"\n\n<pre><code>",
"</code></pre>\n\n",
"<q>",
"</q>",
"\n\n<ul>",
"</ul>\n\n",
"<li>",
"</li>",
"<em>",
"</em>",
"<strong>",
"</strong>"
), $data);
preg_match_all("/<pre>.*?<\/pre>/s",$data, $extract);
for($i=0;$i<sizeof($extract[0]); $i++) {
$data=str_replace($extract[0][$i], "REPLACE$i", $data);
}
/* Put in the <p>'s around text and replaced text */
foreach(preg_split("/\n+Ķ(\r\n)+/", $data) as $token) {
if(strlen($token) == 0) continue;
if(preg_match("/^<.*>$/", $token)) { $s .= "\n".$token; continue; }
$s .= "\n<p>$token</p>\n";
}
for($i=0; $i<sizeof($extract[0]); $i++) {
$s=str_replace("REPLACE$i", $extract[0][$i], $s);
}
return $s;
}[/pre]
Many thanks for all the help guys, hope someone get's some use outta this function besides me...
Nick
Instead of using [em] and [strong] as codes, why not use [b] and [i]? Sure, you can still replace them with <em> and <strong>... It will just make it easier for those who know about <b> and <i>, but not <strong> and <em>
Also, don't you want to replace all < and > in your regexp? < to < and > to > :)
Then replace the style codes with tags...
Thatīs done before calling this function, at least in my code where I copied the original function from. Iīm sure Nick did it as well.
Iīd go for [i] and [b] as well. I know this will be a bit unconsistent on a website on proper CSS [w3.org] usage but I think users will appreciate the shorter tags nevertheless :-). If you want to be more consistent use [s] and [e]. Or provide all three ways and everybody can pick his favorite method.
Andreas