CODE
<?php
function something($info) {
$script = new mirc_script($info);
$script->highlight();
return $script->get_script();
}
class mirc_script {
private $data = array();
public $chars = array();
// By specifying TRUE for $beautify here you can save a bit a processing time rather than call the beautify method later
public function __construct($script = NULL,$beautify = FALSE) {
if ($beautify && $script !== NULL) {
$this->beautify($script);
} else {
$this->script = $script;
}
}
// Attempt to beautify the script a bit
public function beautify($input = NULL) {
// Beautify the script
$script = ($input === NULL ? $this->script : $input);
// Break apart commands separated by |
$script = preg_replace('/\s+\|\s+/',"\n",$script);
// Put newlines before } and after {
$script = preg_replace('/\s+\}\s*(?:\s|$)/',"\n}\n",$script);
$script = preg_replace('/(?<=\s|^)\{\s+/',"{\n",$script);
// Put () around some if conditions
$script = preg_replace('/(if|elseif|while)\s+([^\(].*?)\s+\{/','\1 (\2) {',$script);
$this->script = $script;
}
public function __set($var,$value) {
$this->data[$var] = $value;
if ($var == 'script') {
if ($value !== NULL) {
$this->split_script();
}
}
}
public function __get($var) {
return $this->data[$var];
}
// Split the script into an array of characters
private function split_script() {
$this->script = str_replace("\r",'',$this->script);
$this->chars = array_slice(preg_split('//',$this->script),1,strlen($this->script));
array_map(array(&$this,'escape_chars'),&$this->chars);
}
// Escape HTML characters
private function escape_chars(&$char) {
$char = str_replace(array('&','<','>'),array('&','<','>'),$char);
}
// Apply highlighting to the script
public function highlight() {
$open = '\s,!@^&*\050='; // Characters that start a token
$close = '\s,!@^&*\051'; // Characters that end a token
$script = $this->script;
// Conditional Operators
$operators = '!?(?:=|==|===|>|<|>=|<=|\/\/|\\\\|&|isin|isincs|iswm|isnum|isletter'.
'|isalnum|isalpha|islower|isupper|ison|isop|ishop|isvoice|isvo|isreg|ischan|' .
'isban|isaop|isavoice|isignore|isprotect|isnotify|iswmcs|\|\||&&|\+|\-|\*|%|\^)';
// Patterns to match for different parts of mIRC scripts
$patterns = array(
// Comments
//Block Style
// Here I've put a d in front of the pattern. This is a lazy thing I did to tell the script to delete the matched portion of text. It's not part of the regular expression.
'd/\\013?\s*(\/\*.*?\*\/)\s*\\013?/s'
// The first element of the replacement will go before each callback, and the second element after each callback
=> array('<span class="mirc_comment">','</span>'),
// Single Line
'd/^\s*(;.*)$/m'
=> array('<span class="mirc_comment">','</span>'),
// Number
'/(?<=^|['.$open.'])([+-]?[\d]+?(?:\.[\d]+?)?)(?=$|['.$close.'%])/m'
=> array('<span class="mirc_number">','</span>'),
// Identifier
'/(?<=^|['.$open.'])(\$[^\s\050\051\[,]+)/m'
=> array('<span class="mirc_identifier">','</span>'),
// Identifier Property
'/(?<=\051)(\.[^\s$\051]+)/m'
=> array('<span class="mirc_identifier">','</span>'),
// Variable
'/(?<=^|['.$open.'])(\%[^'.$close.']+)(?=$|['.$close.'])/m'
=> array('<span class="mirc_variable">','</span>'),
// Operators
'/(?<=[\s])('.$operators.')(?=[\s])/m'
=> array('<span class="mirc_operator">','</span>'),
// Special Characters
'/([\[\]\{\}\050\051\|]+)/m'
=> array('<span class="mirc_character">','</span>'),
// Events
'/(?<=^)\s*(on|ctcp|raw)\s+([^\:]+?)
=> array('<span class="mirc_event">','</span>'),
// Commands
'/(?<=^|[\{\|]\s)\s*([^\$\%\s]+?)(?=\s|$)/m'
=> array('<span class="mirc_command">','</span>'),
// Command Switches
'/(?<=^|[\{\|]\s)\s*(?:[^\$\%\s]+?)\s+(-[^\s]+)(?=\s|$)/m'
=> array('<span class="mirc_command_switch">','</span>'),
);
$patterns_keys = array_keys($patterns);
foreach ($patterns_keys as $rpattern) {
// Iterate through each pattern
if ($rpattern{0} == 'd') {
// The 'd' switch means delete the text after matching
$delete = TRUE;
$pattern = substr($rpattern,1);
} else {
$delete = FALSE;
$pattern = $rpattern;
}
if (preg_match_all($pattern,$script,$matches,PREG_OFFSET_CAPTURE)) {
// Get all matches for this pattern
array_shift($matches); // Shift off the part we don't want
foreach ($matches as $matches2) {
// Iterate through each callback
foreach ($matches2 as $match) {
// Iterate through each match of each callback
list($text,$offset) = $match;
// Put the first element before the first character of the callback
$this->chars[$offset] = $patterns[$rpattern][0] . $this->chars[$offset] ;
// Put the second element after the last character of the callback
$this->chars[$offset -1 + strlen($text)] = $this->chars[$offset-1 + strlen($text)] .
$patterns[$rpattern][1];
if ($delete) {
// Delete the entire matched text so we don't match it again
$script = substr($script,0,$offset) . str_repeat(' ',strlen($text)) .
substr($script,$offset + strlen($text));
}
} // End iterate through each match of callback
} // End iterate through each callback
} // End if
} // End iterate through each pattern
return $line;
}
// Returns the script after processing
// Specify TRUE for $indent to have the script indented
public function get_script($indent = FALSE) {
// Implode the array of characters into the finished script
$output = implode('',$this->chars);
if ($indent) {
$lines = explode("\n",$this->script);
$output = explode("\n",$output);
$level = 0;
foreach ($lines as $key => &$line) {
if ($in_comment) {
// Don't indent parts of the script that are commented out
if (preg_match('/^\s*\*\//',$line)) { $in_comment = FALSE; }
continue;
}
// Check for beginning of a comment
if (preg_match('/^\s*\/\*/',$line)) { $in_comment = TRUE; continue; }
if (preg_match('/^\s*;/',$line)) { continue; }
// Remove spaces at the beginning of the line
$output[$key] = preg_replace('/^\s*/','',$output[$key]);
// Decrease indentation if there's a }
$decrease = preg_match_all('/(?<=\s|^)}(?=\s|$)/',$line);
// Increase indentation if there's a {
$increase = preg_match_all('/(?<=\s|^|
// Increase indentation if there's a $&
$increase = preg_match_all('/\$\&\s*$/',$line);
$difference = $increase - $decrease;
if ($difference < 0) { $level += $difference; $difference = 0; }
if ($level < 0) $level = 0;
$output[$key] = str_repeat(' ',$level * 2) . $output[$key];
$level += $difference;
$difference = 0;
}
$output = implode("\n",$output);
}
return $output;
}
}
?>

