Location: PHPKode > scripts > CSS Parser > CSS-Parser-master/parser.php
<?php


/**
 * CSSPARSER
 * Copyright (C) 2009 Peter Kröner
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */



/**
 * CSS PARSER
 * General purpose CSS parser
 */
class CssParser {


	public $css;
	public $parsed;


	/**
	 * LOAD_STRING
	 * Loads a css string
	 */
	public function load_string($string, $overwrite = false){
		if($overwrite){
			$this->css = $string;
		} else {
			$this->css .= $string;
		}
	}


	/**
	 * LOAD_FILE
	 * Loads a file
	 */
	public function load_file($file, $overwrite = false){
		$this->load_string(file_get_contents($file), $overwrite);
	}


	/**
	 * LOAD_FILES
	 * Loads a number of files
	 */
	public function load_files($files){
		$files = explode(';', $files);
		foreach($files as $file){
			$this->load_file($file, false);
		}
	}


	/**
	 * PARSE
	 * Parses some CSS into an array
	 */
	public function parse(){
		$css = $this->css;
		// Remove CSS-Comments
		$css = preg_replace('/\/\*.*?\*\//ms', '', $css);
		// Remove HTML-Comments
		$css = preg_replace('/([^\'"]+?)(\<!--|--\>)([^\'"]+?)/ms', '$1$3', $css);
		// Extract @media-blocks into $blocks
		preg_match_all('/@.+?\}[^\}]*?\}/ms',$css, $blocks);
		// Append the rest to $blocks
		array_push($blocks[0],preg_replace('/@.+?\}[^\}]*?\}/ms','',$css));
		$ordered = array();
		for($i=0;$i<count($blocks[0]);$i++){
			// If @media-block, strip declaration and parenthesis
			if(substr($blocks[0][$i],0,6) === '@media') 
			{
				$ordered_key = preg_replace('/^(@media[^\{]+)\{.*\}$/ms','$1',$blocks[0][$i]);
				$ordered_value = preg_replace('/^@media[^\{]+\{(.*)\}$/ms','$1',$blocks[0][$i]);
			}
			// Rule-blocks of the sort @import or @font-face
			elseif(substr($blocks[0][$i],0,1) === '@')
			{
				$ordered_key = $blocks[0][$i];
				$ordered_value = $blocks[0][$i];
			}
			else 
			{
				$ordered_key = 'main';
				$ordered_value = $blocks[0][$i];
			}
			// Split by parenthesis, ignoring those inside content-quotes
			$ordered[$ordered_key] = preg_split('/([^\'"\{\}]*?[\'"].*?(?<!\\\)[\'"][^\'"\{\}]*?)[\{\}]|([^\'"\{\}]*?)[\{\}]/',trim($ordered_value," \r\n\t"),-1,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
		}
		
		// Beginning to rebuild new slim CSS-Array
		foreach($ordered as $key => $val){
			$new = array();
			for($i = 0; $i<count($val); $i++){
				// Split selectors and rules and split properties and values
				$selector = trim($val[$i]," \r\n\t");
				
				if(!empty($selector)){
					if(!isset($new[$selector])) $new[$selector] = array();
					$rules = explode(';',$val[++$i]);
					foreach($rules as $rule){
						$rule = trim($rule," \r\n\t");
						if(!empty($rule)){
							$rule = array_reverse(explode(':', $rule));
							$property = trim(array_pop($rule)," \r\n\t");
							$value = implode(':', array_reverse($rule));
							
							if(!isset($new[$selector][$property]) || !preg_match('/!important/',$new[$selector][$property])) $new[$selector][$property] = $value;
							elseif(preg_match('/!important/',$new[$selector][$property]) && preg_match('/!important/',$value)) $new[$selector][$property] = $value;
						}
					}
				}
			}
			$ordered[$key] = $new;
		}
		$this->parsed = $ordered;
	}


	/**
	 * GLUE
	 * Turn an array back into CSS
	 */
	public function glue(){
		if($this->parsed){
			$output = '';
			foreach($this->parsed as $media => $content){
				if(substr($media,0,6) === '@media'){
					$output .= $media . " {\n";
					$prefix = "\t";
				}
				else $prefix = "";
				
				foreach($content as $selector => $rules){
					$output .= $prefix.$selector . " {\n";
					foreach($rules as $property => $value){
						$output .= $prefix."\t".$property.': '.$value;
						$output .= ";\n";
					}
					$output .= $prefix."}\n\n";
				}
				if(substr($media,0,6) === '@media'){
					$output .= "}\n\n";
				}
			}
			return $output;
		}
	}


}


?>
Return current item: CSS Parser