Location: PHPKode > scripts > Cruncher class > cruncher-class/Cruncher.class.php
<?php
/**
 * Cruncher class,
 *	single method class to crunch code [default: JavaScript (ActionScript or ECMAScript) source].
 * With a dedicated associative array rules and one regexp should crunch other sources too.
 * ____________________________________
 * @example
 * 	$cruncher = new Crunch;
 *	echo $cruncher->crunch($source, 3);
 * --------------------------------------------------------------
 * @Compatibility	PHP >= 4 and 5 (E_ALL | E_STRICT) error free
 * @Dependencies	SourceMap.class.php
 * @Author	Andrea Giammarchi
 * @Site		http://www.devpro.it/
 * @Date		2007/01/15
 * @LastMod	2007/02/11 [supports JavaScript conditional comments]
 * @Version	1.0
 */
require_once 'SourceMap.class.php';
class Cruncher {
	
	/** 
	 * code rules, by default these are JavaScript (ActionScript or ECMAScript) dedicated
	 * You could change them setting directly this variable
	 * (i.e. $cruncher->rules = array(....))
	 */
	/** public */ var	$rules = array(
		array('name'=>'doublequote', 'start'=>'"', 'end'=>'"', 'noslash'=>true),
		array('name'=>'singlequote', 'start'=>"'", 'end'=>"'", 'noslash'=>true),
		array('name'=>'conditionalcomment', 'start'=>'/*@', 'end'=>'@*/'),
		array('name'=>'singlelinecomment', 'start'=>'//', 'end'=>array("\n", "\r")),
		array('name'=>'multilinecomment', 'start'=>'/*', 'end'=>'*/'),
		array('name'=>'regexp', 'start'=>'/', 'end'=>'/', 'match'=>'#^/[^\x0a\x0d]+/$#', 'noslash'=>true)
	);
	
	/**
	 * regexp to crunch code, by default these are JavaScript (ActionScript or ECMAScript) dedicated
	 * These regexp should be compatible with CSS sources too
	 */
	/** public */ var	$re = array(
		
		// find one or more space and return them as value \\1
		'space'		=> '/([[:space:]]+)/',
		
		// trim common JavaScript operators and return them as value \\1
		'operator'	=> '/[[:space:]]?([\.|\(|\)|;|\:|=|\{|\}|\,|\-|\+|\?|>|<|\*|\/|^|\||\!|&|\[|\]|%]+)[[:space:]]?/'
	);
	
	// "private" instance of SourceMap
	/** private */ var	$__sourceMap = null;
	
	/**
	 * public constructor,
	 *	init a new cruncher setting private __courceMap variable.
	 *
	 *	new Cruncher(Void)
	 */
	/** public /**/ function Cruncher(){
		$this->__sourceMap = new SourceMap;
	}
	
	/**
	 * public method,
	 *	parse a source code and return them crunched
	 *
	 *	self->crunch(source:String [, level:UShortRange(1,3)]):String
	 *
	 * @param	String		the source to parse
	 * @param	UShort		compression level from 1 to 3, default: 1
	 *				level 1 - removes comments and trim spaces of each block of code
	 *				level 2 - removes comments and duplicated spaces(should be regressive)
	 *				level 3 - removes comments and spaces (can be regressive)
	 * @return	String		crunched string
	 */
	/** public /**/ function crunch($str, $level = 1){
		$conditional = create_function('$m', '$tmp=new Cruncher;return $m[1].$tmp->crunch($m[2], '.$level.').$m[3];');
		$evalspace = $this->re['space'].'e';
		$parsed = array();
		$map = $this->__sourceMap->getMap($str, $this->rules);
		--$level;
		for($i = 0, $j = 0, $k = count($map), $name = ''; $j < $k; $j++) {
			$name = &$map[$j]['name'];
			switch($name) {
				case	'singlelinecomment':
				case	'multilinecomment':
					if($level < 2 && $i > 0 && !preg_match("/(\r|\n)$/", $parsed[$i-1]))
						$parsed[$i++] = "\r\n";
					break;
				case	'conditionalcomment':
					$parsed[$i++] = preg_replace_callback(
						'/^(\/\*@)([^\a]*?)(@\*\/)$/',
						$conditional,
						substr($str, $map[$j]['start'], $map[$j]['end'] - $map[$j]['start'])
					);
					break;
				default:
					$parsed[$i] = substr($str, $map[$j]['start'], $map[$j]['end'] - $map[$j]['start']);
					if($name === 'code') {
						switch($level) {
							case	0:
								$parsed[$i] = trim($parsed[$i]);
								break;
							case	1:
								$parsed[$i] = $this->__trimAndReplace($evalspace, 'substr("\\1", 0, 1)', $parsed[$i]);
								break;
							case	2:
								$parsed[$i] = $this->__trimOperatorsAndReplace($parsed[$i]);
								break;
						}
					}
					++$i;
					break;
			}
		}
		return implode('', $parsed);
	}
	
	/**
	 * "private" method,
	 *	replace using a regexp and return trimmed string
	 *
	 *	(self)->__trimAndReplace(re:String, place:String, *source:String):String
	 *
	 * @param	String		regexp to use
	 * @param	String		replacement for used regexp
	 * @param	String		string to change
	 * @param	String		trim and replaced string
	 */
	/** private /**/ function __trimAndReplace($re, $place, &$str){
		return trim(preg_replace($re, $place, $str));
	}
	
	/**
	 * "private" method,
	 *	replace using a regexp and return trimmed string without spaces between operators (defined in self->re['operator'] string)
	 *
	 *	(self)->__trimOperatorsAndReplace(*source:String):String
	 *
	 * @param	String		string to change
	 * @param	String		trim and replaced string without spaces between operators
	 */
	/** private /**/ function __trimOperatorsAndReplace(&$str){
		return preg_replace($this->re['operator'], '\\1', $this->__trimAndReplace($this->re['space'], ' ', $str));
	}
}
?>
Return current item: Cruncher class