protected static function cb_extractStrings($match)
 {
     $label = csscrush::createTokenLabel('s');
     csscrush::$storage->tokens->strings[$label] = $match[0];
     return $label;
 }
 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::createTokenLabel('p');
         $str = $before . $label . $after;
         $match_obj->matches[$label] = $content;
         // Parens will be folded in later
         csscrush::$storage->tokens->parens[$label] = $content;
     }
     $match_obj->string = $str;
     return $match_obj;
 }