squeezr/lib/Tollwerk/Squeezr/Css.php
/**
     * Parse and analyze the requested CSS file
     *
     * @throws \Tollwerk\Squeezr\Exception            On any parser error
     * @todo joschi                                    Implement media query support for @import rules
     */
Parse and analyze the requested CSS file
@throws \Tollwerk\Squeezr\Exception            On any parser error
@todo joschi                                    Implement media query support for @import rules
Parse and analyze the requested CSS file @throws \ Tollwerk \ Squeezr \ Exception On any parser error @todo joschi Implement media query support for @import rules
protected function _parse()
    {
        $origCss = '';
        $length = 0;
        foreach (@file($this->_absoluteCssPath) as $line) {
            $origCss .= $line;
            $length += strlen($line);
            $this->_lines[] = $length;
        }
        $css = $origCss;
        $peek = 0;
        $block = null;
        while ($peek < $length) {
            if (preg_match("%^(\s+)%isSu", $css, $whitespace)) {
                $block .= $whitespace[0];
                $peek += strlen($whitespace[0]);
            } else {
                if (!strncmp('/*', $css, 2)) {
                    $commentEnd = strpos($css, '*/', 2);
                    if ($commentEnd === false) {
                        throw new \Tollwerk\Squeezr\Exception(sprintf(\Tollwerk\Squeezr\Exception::UNBALANCED_BLOCK_COMMENT_STR,
                            $this->_peekToLine($peek)), \Tollwerk\Squeezr\Exception::UNBALANCED_BLOCK_COMMENT);
                    }
                    $commentLength = $commentEnd + 2;
                    $block .= substr($css, 0, $commentLength);
                    $peek += $commentLength;
                } elseif (!strncmp('@', $css, 1)) {
                    if (!preg_match("%^\@([\w\-]+)%", $css, $atRule)) {
                        throw new \Tollwerk\Squeezr\Exception(sprintf(\Tollwerk\Squeezr\Exception::INVALID_AT_RULE_IDENTIFIER_STR,
                            $this->_peekToLine($peek)), \Tollwerk\Squeezr\Exception::INVALID_AT_RULE_IDENTIFIER);
                    }
                     by identifier
                    switch ($atRule[1]) {
                        case 'media':
                            $declarationBlockStart = 0;
                            $declarationBlock = $this->_consumeDeclarationBlock($css, $peek, strlen($atRule[1]) + 1,
                                $declarationBlockStart);
                            $peek += strlen($declarationBlock);
                            $breakpoints = $this->_breakpoints(substr($css, 6, $declarationBlockStart - 6));
                            if (is_array($breakpoints)) {
                                if (strlen($block)) {
                                    $this->_registerBlock($block);
                                }
                                $this->_registerBlock($declarationBlock, $breakpoints);
                            } else {
                                $block .= $declarationBlock;
                            }
                            break;
                        case 'import':
                            if (preg_match("%[\r\n\;]%", $css, $delimiter, PREG_OFFSET_CAPTURE, strlen($atRule[1]))) {
                                $declarationBlock = substr($css, 0, $delimiter[0][1] + 1);
                            } else {
                                $declarationBlock = $css;
                            }
                            $peek += strlen($declarationBlock);
                            $import = trim(substr($declarationBlock, 7), ' ;');
                            foreach (self::$_importPatterns as $start => $pattern) {
                                if (!strncmp($start, $import, strlen($start)) && preg_match($pattern, $import,
                                        $importMediaQuery)
                                ) {
                                    $breakpoints = $this->_breakpoints($importMediaQuery[4]);
                                    if (is_array($breakpoints)) {
                                        if (strlen($block)) {
                                            $this->_registerBlock($block);
                                        }
                                        $this->_registerBlock($declarationBlock, $breakpoints);
                                        break 2;
                                    }
                                }
                            }
                            $block .= $declarationBlock;
                            break;
                        case 'charset';
                        case 'namespace':
                            if (preg_match("%[\r\n\;]%", $css, $delimiter, PREG_OFFSET_CAPTURE, strlen($atRule[1]))) {
                                $block .=
                                $declarationBlock = substr($css, 0, $delimiter[0][1] + 1);
                                $peek += strlen($declarationBlock);
                            } else {
                                $block .= $css;
                                $peek += strlen($css);
                            }
                            break;
                        case 'page':
                        case 'font-face':
                        default:
                            $block .=
                            $declarationBlock = $this->_consumeDeclarationBlock($css, $peek, strlen($atRule[1]) + 1);
                            $peek += strlen($declarationBlock);
                            break;
                    }
                } else {
                    $block .=
                    $declarationBlock = $this->_consumeDeclarationBlock($css, $peek);
                    $peek += strlen($declarationBlock);
                }
            }
            $css = substr($origCss, $peek);
        }
        if (strlen($block)) {
            $this->_registerBlock($block);
        }
    }
protected function _parse ( ) { $ origCss = '' ; $ length = 0 ; foreach ( @ file ( $ this -> _absoluteCssPath ) as $ line ) { $ origCss .= $ line ; $ length += strlen ( $ line ) ; $ this -> _lines [ ] = $ length ; } $ css = $ origCss ; $ peek = 0 ; $ block = null ; while ( $ peek < $ length ) { if ( preg_match ( " %^(\s+)%isSu " , $ css , $ whitespace ) ) { $ block .= $ whitespace [ 0 ] ; $ peek += strlen ( $ whitespace [ 0 ] ) ; } else { if ( ! strncmp ( '/*' , $ css , 2 ) ) { $ commentEnd = strpos ( $ css , '*/' , 2 ) ; if ( $ commentEnd === false ) { throw new \ Tollwerk \ Squeezr \ Exception ( sprintf ( \ Tollwerk \ Squeezr \ Exception :: UNBALANCED_BLOCK_COMMENT_STR , $ this -> _peekToLine ( $ peek ) ) , \ Tollwerk \ Squeezr \ Exception :: UNBALANCED_BLOCK_COMMENT ) ; } $ commentLength = $ commentEnd + 2 ; $ block .= substr ( $ css , 0 , $ commentLength ) ; $ peek += $ commentLength ; } elseif ( ! strncmp ( '@' , $ css , 1 ) ) { if ( ! preg_match ( " %^\@([\w\-]+)% " , $ css , $ atRule ) ) { throw new \ Tollwerk \ Squeezr \ Exception ( sprintf ( \ Tollwerk \ Squeezr \ Exception :: INVALID_AT_RULE_IDENTIFIER_STR , $ this -> _peekToLine ( $ peek ) ) , \ Tollwerk \ Squeezr \ Exception :: INVALID_AT_RULE_IDENTIFIER ) ; } switch ( $ atRule [ 1 ] ) { case 'media' : $ declarationBlockStart = 0 ; $ declarationBlock = $ this -> _consumeDeclarationBlock ( $ css , $ peek , strlen ( $ atRule [ 1 ] ) + 1 , $ declarationBlockStart ) ; $ peek += strlen ( $ declarationBlock ) ; $ breakpoints = $ this -> _breakpoints ( substr ( $ css , 6 , $ declarationBlockStart - 6 ) ) ; if ( is_array ( $ breakpoints ) ) { if ( strlen ( $ block ) ) { $ this -> _registerBlock ( $ block ) ; } $ this -> _registerBlock ( $ declarationBlock , $ breakpoints ) ; } else { $ block .= $ declarationBlock ; } break ; case 'import' : if ( preg_match ( " %[ \r \n \;]% " , $ css , $ delimiter , PREG_OFFSET_CAPTURE , strlen ( $ atRule [ 1 ] ) ) ) { $ declarationBlock = substr ( $ css , 0 , $ delimiter [ 0 ] [ 1 ] + 1 ) ; } else { $ declarationBlock = $ css ; } $ peek += strlen ( $ declarationBlock ) ; $ import = trim ( substr ( $ declarationBlock , 7 ) , ' ;' ) ; foreach ( self :: $ _importPatterns as $ start => $ pattern ) { if ( ! strncmp ( $ start , $ import , strlen ( $ start ) ) && preg_match ( $ pattern , $ import , $ importMediaQuery ) ) { $ breakpoints = $ this -> _breakpoints ( $ importMediaQuery [ 4 ] ) ; if ( is_array ( $ breakpoints ) ) { if ( strlen ( $ block ) ) { $ this -> _registerBlock ( $ block ) ; } $ this -> _registerBlock ( $ declarationBlock , $ breakpoints ) ; break 2 ; } } } $ block .= $ declarationBlock ; break ; case 'charset' ; case 'namespace' : if ( preg_match ( " %[ \r \n \;]% " , $ css , $ delimiter , PREG_OFFSET_CAPTURE , strlen ( $ atRule [ 1 ] ) ) ) { $ block .= $ declarationBlock = substr ( $ css , 0 , $ delimiter [ 0 ] [ 1 ] + 1 ) ; $ peek += strlen ( $ declarationBlock ) ; } else { $ block .= $ css ; $ peek += strlen ( $ css ) ; } break ; case 'page' : case 'font-face' : default : $ block .= $ declarationBlock = $ this -> _consumeDeclarationBlock ( $ css , $ peek , strlen ( $ atRule [ 1 ] ) + 1 ) ; $ peek += strlen ( $ declarationBlock ) ; break ; } } else { $ block .= $ declarationBlock = $ this -> _consumeDeclarationBlock ( $ css , $ peek ) ; $ peek += strlen ( $ declarationBlock ) ; } } $ css = substr ( $ origCss , $ peek ) ; } if ( strlen ( $ block ) ) { $ this -> _registerBlock ( $ block ) ; } }
Parse and analyze the requested CSS file
 @throws \Tollwerk\Squeezr\Exception            On any parser error
 @todo joschi                                    Implement media query support for @import rules
Parse and analyze the requested CSS file @throws \ Tollwerk \ Squeezr \ Exception On any parser error @todo joschi Implement media query support for @import rules
// Consume all CSS data (blockwise) // Consume whitespace // Consume Block comment // If no comment end is found: Error // Consume @-rule // Determine the rule identifier // Consume @-rule by identifier // @media rule // If the @media query is squeezable // If there's already block data to be registered // Else: Not a squeezable @media query, register as regular block // @import rule: May contain media query, should be implemented // Find the next line break or semicolon // Else: this must be the end of the data // Examine the import rule // If the @import rule has a squeezable media query part // If there's already block data to be registered // Single line @-rules (except @import) // Find the next line break or semicolon // Else: this must be the end of the data // Block @-rules (e.g. *-keyframes) // Consume declaration blocks // Register the last block (if any)