Location: PHPKode > scripts > CSS Crush > peteboere-css-crush-465ad01/lib/Util.php
<?php
/**
 *
 *  Utilities
 *
 */

class csscrush_util {


	// Create html attribute string from array
	public static function htmlAttributes ( array $attributes ) {

		$attr_string = '';
		foreach ( $attributes as $name => $value ) {
			$value = htmlspecialchars( $value, ENT_COMPAT, 'UTF-8', false );
			$attr_string .= " $name=\"$value\"";
		}
		return $attr_string;
	}


	public static function normalizeSystemPath ( $path, $strip_ms_dos = false ) {

		$path = rtrim( str_replace( '\\', '/', $path ), '/' );
		
		if ( $strip_ms_dos ) {
			$path = preg_replace( '!^[a-z]\:!i', '', $path ); 
		}
		return $path;
	}


	public static function find () {

		foreach ( func_get_args() as $file ) {
			$file_path = csscrush::$config->location . '/' . $file;
			if ( file_exists( $file_path ) ) {
				return $file_path;
			}
		}
		return false;
	}


	public static function stripComments ( $str ) {
		return preg_replace( csscrush_regex::$patt->commentToken, '', $str );
	}


	public static function normalizeWhiteSpace ( $str ) {

		$replacements = array(
			'!\s+!'                             => ' ',
			'!(\[)\s*|\s*(\])|(\()\s*|\s*(\))!' => '${1}${2}${3}${4}',  // Trim internal bracket WS
			'!\s*(;|,|\/|\!)\s*!'               => '$1',     // Trim WS around delimiters and special characters
		);
		return preg_replace(
			array_keys( $replacements ), array_values( $replacements ), $str );
	}


	public static function tokenReplace ( $string, $token_replace, $type = 'parens' ) {

		// The tokens to replace
		$token_replace = (array) $token_replace;

		// Reference the token table
		$token_table =& csscrush::$storage->tokens->{ $type };

		// Replace the tokens listed
		foreach ( $token_replace as $token ) {
			if ( isset( $token_table[ $token ] ) ) {
				$string = str_replace( $token, $token_table[ $token ], $string );
			}
		}

		return $string;
	}


	public static function tokenReplaceAll ( $str, $type = 'parens' ) {

		// Only $type 'parens' or 'strings' make any sense
		$token_patt = 'parenToken';

		if ( $type === 'strings' ) {
			$token_patt = 'stringToken';
		}

		// Reference the token table
		$token_table =& csscrush::$storage->tokens->{ $type };

		// Find tokens
		$matches = csscrush_regex::matchAll( csscrush_regex::$patt->{ $token_patt }, $str );
	
		foreach ( $matches as $m ) {
			
			$token = $m[0][0];
			
			if ( isset( $token_table[ $token ] ) ) {
			
				$str = str_replace( $token, $token_table[ $token ], $str );
			}
		}
		return $str;
	}


	public static function splitDelimList ( $str, $delim, $fold_in = false, $trim = false ) {

		$match_obj = self::matchAllBrackets( $str );

		// If the delimiter is one character do a simple split
		// Otherwise do a regex split 
		if ( 1 === strlen( $delim ) ) {
			$match_obj->list = explode( $delim, $match_obj->string );
		}
		else {
			$match_obj->list = preg_split( '!' . $delim . '!', $match_obj->string );
		}

		if ( true === $trim ) {
			$match_obj->list = array_map( 'trim', $match_obj->list );
		}

		// Filter out empties
		$match_obj->list = array_filter( $match_obj->list );
		
		if ( $fold_in ) {

			foreach ( $match_obj->list as &$item ) {
				$item = csscrush_util::tokenReplace( $item, $match_obj->matches );
			}
		}
		return $match_obj;
	}


	public static function matchBrackets ( $str, $brackets = array( '(', ')' ), 
				$search_pos = 0, $capture_text = false ) {

		list( $opener, $closer ) = $brackets;
		$openings = array();
		$closings = array();
		$brake = 50; // Set a limit in the case of errors

		$match = new stdclass();

		$start_index = strpos( $str, $opener, $search_pos );
		$close_index = strpos( $str, $closer, $search_pos );

		if ( $start_index === false ) {

			return false;
		}
		if ( substr_count( $str, $opener ) !== substr_count( $str, $closer ) ) {

		 	$sample = substr( $str, 0, 25 );
			trigger_error( __METHOD__ . ": Unmatched token near '$sample'.\n", E_USER_WARNING );
			return false;
		}

		while (
			( $start_index !== false || $close_index !== false ) && $brake--
		) {
			if ( $start_index !== false && $close_index !== false ) {
				$search_pos = min( $start_index, $close_index );
				if ( $start_index < $close_index ) {
					$openings[] = $start_index;
				}
				else {
					$closings[] = $close_index;
				}
			}
			elseif ( $start_index !== false ) {
				$search_pos = $start_index;
				$openings[] = $start_index;
			}
			else {
				$search_pos = $close_index;
				$closings[] = $close_index;
			}
			$search_pos += 1; // Advance

			if ( count( $closings ) === count( $openings ) ) {

				$match->openings = $openings;
				$match->start = $start = $openings[0];
				$match->closings = $closings;
				$match->end = $closings[ count( $closings ) - 1 ] + 1;

				if ( $capture_text ) {
					// Text capturing is optional to avoid using memory when not necessary
					$match->inside = substr( $str, $start + 1, $match->end - $start - 2 );
					$match->after = substr( $str, $match->end );
				}

				return $match;
			}
			$start_index = strpos( $str, $opener, $search_pos );
			$close_index = strpos( $str, $closer, $search_pos );
		}

		trigger_error( __METHOD__ . ": Reached brake limit of '$brake'. Exiting.\n", E_USER_WARNING );
		return false;
	}


	public static function matchAllBrackets ( $str, $pair = '()', $offset = 0 ) {

		$match_obj = new stdclass();
		$match_obj->string = $str;
		$match_obj->raw = $str;
		$match_obj->matches = array();

		list( $opener, $closer ) = str_split( $pair, 1 );

		// Return early if there's no match
		if ( false === ( $first_offset = strpos( $str, $opener, $offset ) ) ) {
			return $match_obj;
		}

		// Step through the string one character at a time storing offsets
		$paren_score = -1;
		$inside_paren = false;
		$match_start = 0;
		$offsets = array();

		for ( $index = $first_offset; $index < strlen( $str ); $index++ ) {
			$char = $str[ $index ];

			if ( $opener === $char ) {
				if ( ! $inside_paren ) {
					$paren_score = 1;
					$match_start = $index;
				}
				else {
					$paren_score++;
				}
				$inside_paren = true;
			}
			elseif ( $closer === $char ) {
				$paren_score--;
			}

			if ( 0 === $paren_score ) {
				$inside_paren = false;
				$paren_score = -1;
				$offsets[] = array( $match_start, $index + 1 );
			}
		}

		// Step backwards through the matches
		while ( $offset = array_pop( $offsets ) ) {

			list( $start, $finish ) = $offset;

			$before = substr( $str, 0, $start );
			$content = substr( $str, $start, $finish - $start );
			$after = substr( $str, $finish );

			$label = csscrush::tokenLabelCreate( 'p' );
			$str = $before . $label . $after;
			$match_obj->matches[] = $label;

			// Parens will be folded in later
			csscrush::$storage->tokens->parens[ $label ] = $content;
		}

		$match_obj->string = $str;

		return $match_obj;
	}
}


/**
 *
 *  String sugar
 *
 */

class csscrush_string {

	public $token;

	public $value;

	public $raw;

	public $quoteMark;

	public function __construct ( $token ) {
		
		$this->token = trim( $token );
		$this->raw = csscrush::$storage->tokens->strings[ $token ];
		$this->value = trim( $this->raw, '\'"' );
		$this->quoteMark = $this->raw[0];
	}
	
	public function update ( $newValue ) {
		csscrush::$storage->tokens->strings[ $this->token ] = $newValue;
	}
}


Return current item: CSS Crush