<? /** * Object Oriented CSS 2.0 * September 5, 2009 * Corey Hart @ http://www.codenothing.com * * Credit to Thiemo Mättig @ http://maettig.com/ for his regex help */
Class ObjectOrientedCSS { /** * Class Vars * * @param (array) vars: Holds variables found in css file * @param (string) file: Contents of css file * @param (array) tree: Holds parsed tree found in css file */ var $vars = array(); var $file = ''; var $tree = array();
/** * Centralized function to run the OOCSS Parser * * @param (string) css: Contents of css file */ function run($css){ // Store contents into class var $this->file = $css;
// Raw file trimmed down to single line $this->trimCSS();
// Run variable conversions first $this->variableReplacement();
// Loop through and create the tree (Pass file as var, for loop) $this->prepFileForLoop(); $this->tree = $this->convertLoop($this->file);
// Process tree for output (Pass as var, for loops) $this->file = $this->processFile($this->tree);
// Return parsed file for quick output return $this->file; }
/** * Format the css file into single line * * @params none */ function trimCSS(){ // Remove CSS Comments $this->file = preg_replace("/\/\*(.*?)\*\//s", '', $this->file); // Remove Multiple Spaces (Credit goes to Thiemo Mättig @ http://maettig.com/ for pointing out this regex) $this->file = preg_replace("/\s+/s", ' ', $this->file); }
/** * Find and replace variables * * @params none */ function variableReplacement(){ // Credit goes to Thiemo Mättig @ http://maettig.com/ for pointing out this regex preg_match_all("/([$]\w+)\s*=\s*([^;]+);/s", $this->file, $matches); for ($i=0, $imax=count($matches[0]); $i<$imax; $i++){ // Matches $string = $matches[0][$i]; $var = $matches[1][$i]; $value = $matches[2][$i];
// Check for multiple definitions if (strpos($value, '{') !== false){ $value = str_replace('{', '', $value); $value = str_replace('}', '', $value); $value = str_replace(',', ';', $value); }
// Store the var for debugging $this->vars[$var] = $value;
// Remove the declaration from the file $this->file = str_replace($string, '', $this->file);
// Enforce semi-colon replacement $this->file = str_replace($var.';', $value.';', $this->file); } }
/** * Reformat css contents into seperate lines * for line-by-line parsing * * @params none */ function prepFileForLoop(){ // Line out as much as possible $this->file = preg_replace("/([{]|[}]|;)/", "$1\n", $this->file);
// Return each line $this->file = explode("\n", str_replace('}', "\n}", $this->file)); }
/** * Create tree structure from formatted contents. * Recursively calls itself to reach multiple levels * * @param (array) file: Reformated css contents */ function convertLoop(&$file){ $ret = $old = array(); while ($file){ $line = trim(array_shift($file)); if (!$line || $line == ''){ continue; } else if (strpos($line, '{') !== false){ // Take out the tag $tag = trim(array_shift(explode('{', $line)));
// Store old tag for merging if (isset($ret[$tag])) $old = $ret;
// Run recursive loop of all levels $ret[$tag] = $this->convertLoop($file);
// If old tag found, merge results if ($old){ $ret = array_merge_recursive($old, $ret); $old = array(); } } else if (strpos($line, '}') !== false){ return $ret; } else{ $ret['props'][] = $line; } } return $ret; }
/** * Create standard CSS file from processed tree * * @param (array) file: Tree parsed from contents * @param (string) tag: Current tag depth */ function processFile($file, $tag=''){ // Only add props if it exists with a tag if (($tag = trim($tag)) && $tag != '' && $file['props']){ // Remove Lingering direct descendent tag and trim it $trimedTag = trim(preg_replace('/[>]$/', '', $tag)); $str = "$trimedTag {\n\t" . implode("\n\t", $file['props']) . "\n}\n\n"; }
// Loop through nested levels foreach ($file as $key => $value) if ($key != 'props') $str .= $this->processFile($value, $tag.' '.$key);
// Return concatenated string return $str; } };
$oocss = new ObjectOrientedCSS; ?>
|