Yksinkertainen BBCode parseri, jota käytetää yleisesti foorumeilla. Huomasin että jotkin parserit ovat joko liian yksinkertaisia tai vaikeasti muokattavia omaan käyttöön.
<?php
/*
Created by NiLon
Free for non-profit usage ;)
Fast and lightwave BBCode parser.
See BBCodeGreedCallback() and BBCodeCallback() for own tags.
*/
function BBCode($string,$escaped=false) { // string BBCode ( string arg [, bool escaped] )
$string = htmlspecialchars($string); // Ignore HTML
if ($escaped) { // Turns escaped tag's to HTMl entities
$string = str_replace(array('\[','\]'),array('[',']'),$string);
}
$pattern = '/\[(\w+)(?:=([^\]]+))?\]([^\[]*)\[\/\1\]/'; // For normal tags
$greedpattern = '/\[(code)(?:=([^\]]+))?\](.+?)\[\/\1\]/s'; // Greed tags
$string = preg_replace_callback($greedpattern,'BBCodeGreedCallback',$string); // Call BBCodeGreedCallback() with match
while (preg_match($pattern,$string)) { // Handle multiple tags with callback
$string = preg_replace_callback($pattern,'BBCodeCallback',$string);
}
$string = BBCodeEscape($string,true); // Turn tag characters back from entities
return $string;
}
function BBCodeGreedCallback($match) { // [tagname=parameter]text[/tagname]
$tagname = $match[1];
$parameter = $match[2];
$text = BBCodeEscape($match[3]);
$deftext = html_entity_decode($match[3]); // For parsers
$output = '';
switch ($tagname) {
case 'code': // Alternative ways to handle [code] tags; [code], [code=language]
if ($parameter == '') { // If no language specified
$output = '<br /><div style="margin: 0px 2%"><strong>Code:</strong><div style="border: 1px solid #666; background-color: #eee">'.$text.'</div></div>';
}
$langs = array( // How it should be written and how to show
'php' => 'PHP',
'cpp' => 'C++',
'python' => 'Python',
'java' => 'Java',
'perl' => 'Perl',
'asm' => 'Assembly',
'html4strict' => 'html',
'mirc' => 'mIRC'
);
if (array_key_exists($parameter, $langs)) { // If such language exists
// Possible to use your own syntax highlight parser
$output = BBCodeSyntaxHighlight($deftext,$parameter,$langs[$parameter]);
}
break;
default: // Just escape tag characters so it will be ignored next time
$output = BBCodeEscape($match[0]);
}
return $output;
}
function BBCodeCallback($match) { // [tagname=parameter]text[/tagname]
$tagname = $match[1];
$parameter = $match[2];
$text = $match[3];
$output = '';
switch ($tagname) {
case 'url': // [url=url]text[/url], [url]url[/url]
if ($parameter == '') { $parameter = $text; }
if (!preg_match('/^\w+:\/\//',$parameter)) { $parameter = 'http://'.$parameter; } // Corrects url
$urlmatch = '/^(?:([a-z.+-]+):\/\/|())(?:([^@:]+)(?::(.*?)|())@|()())([a-z0-9.-]+)(?::(\d+)|())(\/.*)?$/i';
if (preg_match($urlmatch,$parameter)) { // Check if it's url
$output = "<a href=\"$parameter\">$text</a>";
} else {
$output = BBCodeEscape($match[0]);
}
break;
case 'img':
if (!preg_match('/^\w+:\/\//',$text)) { $text = 'http://'.$text; }
$urlmatch = '/^(?:([a-z.+-]+):\/\/|())(?:([^@:]+)(?::(.*?)|())@|()())([a-z0-9.-]+)(?::(\d+)|())(\/.*)?$/i';
if (preg_match($urlmatch,$text)) {
$output = "<img src=\"$text\" alt=\"$text\" />";
} else {
$output = BBCodeEscape($match[0]);
}
break;
case 'b':
$output = "<strong>$text</strong>"; break;
case 'i':
$output = "<i>$text</i>"; break;
case 'u':
$output = "<span style=\"text-decoration: underline\">$text</span>"; break;
case 'color': // Text color; [color=#hexacode]text[/color]
if (preg_match('/^#([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$/',$parameter)) { // Check if hexacode is valid
$output = "<span style=\"color: $parameter\">$text</span>";
} else {
$output = BBCodeEscape($match[0]);
}
break;
case 'size': // Font size; [size=px]text[/size]
if (preg_match('/^\d+$/',$parameter)) { // Only allow reasonable values
if ($parameter < 6 || $parameter > 24) { $parameter = 'normal'; }
$output = "<span style=\"font-size: {$parameter}px\">$text</span>";
} else {
$output = BBCodeEscape($match[0]);
}
break;
case 'quote': // [quote]text[quote]
$writer = $parameter!=''?'<span style="font-size: smaller">'.$parameter.' wrote:</span><br />':'';
$output = '<br /><div style="margin: 0px 2%"><strong>Quote:</strong><div style="border: 1px solid #666; background-color: #eee;">'.$writer.$text.'</div></div>';
break;
default:
$output = BBCodeEscape($match[0]);
}
return $output;
}
function BBCodeEscape($str,$reversed=false) {
if ($reversed) {
return str_replace(array('[',']'),array('[',']'),$str);
}
return str_replace(array('[',']'),array('[',']'),$str);
}
function BBCodeSyntaxHighlight($data,$lang,$alang) {
$source = "<span style=\"color: #00f\">$data</span>";
return '<br /><div style="margin: 0px 2%;"><strong>'.$alang.':</strong><div style="border: 1px solid #666; background-color: #eee">'.$source.'</div></div>';
}
?>Hauskasti muokkasi tuota yhtä kommenttia ".. to handle [koodi] tags; [koodi], ...". Alkuperin siinä luki [ code ] :)
Jonkunsortin demo nähtävissä http://nilon.ath.cx/~nilon/bbcode/
Hieno.
Aihe on jo aika vanha, joten et voi enää vastata siihen.