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: 8 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 < 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));
    }
}
?>