Login   Register  
PHP Classes
elePHPant
Icontem

File: Cruncher.class.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Andrea Giammarchi  >  Cruncher class  >  Cruncher.class.php  >  Download  
File: Cruncher.class.php
Role: Class source
Content type: text/plain
Description: Cruncher core
Class: Cruncher class
Compact source code removing comments and spaces
Author: By
Last change: Version 1.0 with conditional comments support tested on FireFox, Opera, IE and other browsers.
Date: 7 years ago
Size: 5,149 bytes
 

Contents

Class file image Download
<?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 && $i && !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));
    }
}
?>